This guide will help you migrate from the in-memory data store to PostgreSQL on Render.com.
- Creating PostgreSQL Database on Render
- Initializing the Database
- Environment Variables
- Local Development
- Troubleshooting
- Log in to your Render Dashboard
- Click "New +" button → Select "PostgreSQL"
- Configure your database:
- Name:
matchplay-data(or your preferred name) - Database:
matchplay - User: Auto-generated
- Region: Choose same region as your backend service
- Instance Type:
- Free tier for testing/development
- Starter or higher for production
- Name:
- Click "Create Database"
- Wait for database to be provisioned (usually 1-2 minutes)
Once created, Render will provide:
- Internal Database URL (for services in same region):
postgresql://user:password@host:5432/database - External Database URL (for external access):
postgresql://user:password@external-host:5432/database
Important: Use the Internal Database URL for your backend service for better performance and security.
-
Install dependencies (if not already done):
cd backend npm install -
Set DATABASE_URL environment variable in Render:
- Go to your Backend Web Service on Render
- Navigate to "Environment" tab
- Add environment variable:
- Key:
DATABASE_URL - Value: Your PostgreSQL Internal Database URL
- Key:
- Click "Save Changes"
-
Initialize the database (one-time setup):
Option A: Connect to Render Shell
# From Render Dashboard → Your Service → Shell npm run db:initOption B: Connect locally using External URL
# Windows PowerShell $env:DATABASE_URL="your-external-database-url-here" npm run db:init
This will:
- Create all tables (athletes, gamedays, gameday_athletes, matches)
- Set up indexes and triggers
- Insert 12 sample athletes
Required environment variable:
| Key | Value | Description |
|---|---|---|
DATABASE_URL |
postgresql://user:pass@host:5432/db |
Internal Database URL from Render |
NODE_ENV |
production |
Environment mode |
Create a .env file in the backend directory:
DATABASE_URL=postgresql://localhost:5432/matchplay_dev
NODE_ENV=development
PORT=3001Install dotenv and update server.js:
npm install dotenvAdd to top of server.js:
import 'dotenv/config'- Stores player information
- Fields: id, name, email, status, rank
- 12 sample athletes pre-populated
- Stores game day events
- Fields: id, date, venue, status, format, settings
- Links athletes to game days (many-to-many)
- Composite key: (gameday_id, athlete_id)
- Stores all matches
- Fields: id, gameday_id, round, match_group, teams, scores, winner
After redeployment, look for:
✅ Database connection established
📍 Running on http://0.0.0.0:10000
# Replace with your actual backend URL
curl https://your-backend.onrender.com/api/athletes
curl https://your-backend.onrender.com/healthExpected response from /api/athletes:
[
{
"id": "ath-1",
"name": "John Smith",
"email": "john@example.com",
"status": "active",
"rank": 1
},
...
]Solution:
- Verify
DATABASE_URLis correct in Render environment variables - Ensure using Internal Database URL (not External)
- Check database is active on Render dashboard
- Restart the backend service
Solution: Database not initialized
# Connect to Render shell and run:
npm run db:initSolution:
- Go to Render database page
- Copy fresh Internal Database URL
- Update
DATABASE_URLenvironment variable - Redeploy service
Solution:
- Verify using Internal URL (not External)
- Ensure backend and database in same region
- Consider upgrading database tier
Complete these steps in order:
- Create PostgreSQL database on Render
- Copy Internal Database URL
- Add
DATABASE_URLto backend environment variables - Deploy backend with updated code (with pg dependency)
- Run
npm run db:initto initialize database - Check Render logs for successful connection
- Test API endpoints
- Test frontend connectivity
- Verify data persistence (create game day, refresh page)
- ✅ Data now persists across deployments
- ✅ All routes are now async/await
- ✅ Better error handling
- ✅ Production-ready database with indexes
- ✅ Sample data pre-loaded
backend/database/db.js- Connection poolbackend/database/queries.js- All database operationsbackend/database/schema.sql- Database schemabackend/database/init.js- Initialization scriptbackend/DATABASE_SETUP.md- This guide
backend/routes/*.js- All routes use databasebackend/package.json- Added pg dependency
backend/data/store.js- Can be safely deleted
Render automatically backs up your database:
- Free tier: 7 days of backups
- Paid tiers: 30+ days of backups
To restore:
- Go to database on Render
- "Backups" tab
- Select backup
- Click "Restore"
After successful migration:
- Delete old store.js:
backend/data/store.jsis no longer used - Monitor logs: Check for any database errors
- Test thoroughly: Create game days, matches, etc.
- Set up monitoring: Use Render metrics
- Plan for scaling: Monitor database performance
DATABASE_URL=postgresql://username:password@host:5432/database_name
npm run db:initnode -e "import('./database/db.js').then(db => db.query('SELECT NOW()'))"Render Dashboard → Your Service → Logs tab