Configuration
Complete reference for TimeTiles environment variables and settings.
Environment Variables
Required Variables
These must be set for TimeTiles to function:
# Database Connection
DATABASE_URL=postgresql://user:password@localhost:5432/timetiles
# Security (generate with: openssl rand -base64 32)
PAYLOAD_SECRET=your-secret-key-minimum-32-charactersApplication Settings
# Environment
NODE_ENV=development|production
# Application URLs
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_PAYLOAD_URL=http://localhost:3000
# Logging
LOG_LEVEL=info|debug|warn|errorGeocoding Configuration
TimeTiles supports multiple geocoding providers configured through the admin panel:
Geocoding Providers
Configure providers directly in the admin interface at /admin/collections/geocoding-providers:
- Add multiple providers with different priorities
- Enable/disable providers without restart
- Set API keys securely in the admin UI
- Configure rate limits per provider
- Tag providers for environment-specific selection (production, development, testing)
Default Setup (Development Seeding):
- Nominatim (OpenStreetMap): Enabled by default, free public instance, no API key required
- Google Maps: Disabled by default, configure API key in admin panel to enable
- OpenCage: Disabled by default, configure API key in admin panel to enable
Supported Providers:
- Google Maps: Most accurate, requires API key
- OpenCage: Good alternative, requires API key
- Nominatim/OpenStreetMap: Free, no API key needed
Providers are tried in priority order (lower number = higher priority).
Geocoding Settings
Configure geocoding behavior at /admin/globals/settings:
- Enable/Disable Geocoding: Toggle geocoding globally
- Provider Fallback: Enable fallback to alternative providers on failure
- Selection Strategy: Priority-based or tag-based provider selection
- Caching: Enable/disable geocoding cache and set TTL (days)
File Upload Configuration
Control file size limits and upload directories:
# Maximum file sizes in bytes
MAX_FILE_SIZE_AUTHENTICATED=104857600 # 100MB for authenticated users
MAX_FILE_SIZE_UNAUTHENTICATED=10485760 # 10MB for unauthenticated users
# Upload Directory Configuration (relative to apps/web or absolute paths)
UPLOAD_DIR_MEDIA=media # Directory for media uploads (images)
UPLOAD_DIR_IMPORT_FILES=import-files # Directory for import file uploads
UPLOAD_TEMP_DIR=./tmp # Temporary directory for file processingRate Limiting
Configure rate limits for unauthenticated users:
RATE_LIMIT_FILE_UPLOAD=5 # 5 uploads per hour
RATE_LIMIT_PROGRESS_CHECK=100 # 100 progress checks per hour
RATE_LIMIT_API_GENERAL=50 # 50 general API requests per hour
RATE_LIMIT_WINDOW_MS=3600000 # 1 hour window in millisecondsBatch Processing
Adjust these values to tune performance vs memory usage:
BATCH_SIZE_DUPLICATE_ANALYSIS=5000 # Memory efficient for duplicate detection
BATCH_SIZE_SCHEMA_DETECTION=10000 # Larger batches for schema building efficiency
BATCH_SIZE_EVENT_CREATION=1000 # Smaller to avoid transaction timeouts
BATCH_SIZE_DATABASE_CHUNK=1000 # Database query chunk sizeCache Configuration
Generic cache system settings:
CACHE_BACKEND=filesystem # Cache backend: memory or filesystem
CACHE_DEFAULT_TTL=3600 # Default cache TTL in seconds (1 hour)
CACHE_MAX_SIZE_MB=500 # Maximum cache size in MB
CACHE_MAX_ENTRIES=1000 # Maximum number of cache entries (memory backend)
CACHE_DIR=.cache # Base cache directory (filesystem backend)
CACHE_CLEANUP_INTERVAL_MS=3600000 # Cache cleanup interval (1 hour)Geocoding Cache
Configure location cache cleanup:
GEOCODING_CACHE_CLEANUP_DAYS=90 # Days before cleaning up unused cache entries
GEOCODING_CACHE_MIN_HITS=3 # Minimum hits required to keep cache entryURL Fetch Cache
For scheduled URL imports (outgoing requests):
URL_FETCH_CACHE_DIR=/tmp/url-fetch-cache # Directory for URL fetch cache storage
URL_FETCH_CACHE_MAX_SIZE=104857600 # Maximum cache size in bytes (100MB)
URL_FETCH_CACHE_TTL=3600 # Default TTL in seconds
URL_FETCH_CACHE_RESPECT_CACHE_CONTROL=true # Respect Cache-Control headers from external APIsTest Database Configuration
Test databases are automatically derived from DATABASE_URL:
- E2E tests use:
${database}_test(e.g.,timetiles_test) - Unit/Integration tests use:
${database}_test_${worker_id}(e.g.,timetiles_test_1,timetiles_test_2)
No additional configuration needed - the test infrastructure handles this automatically.
Production vs Development
Development Settings (.env)
NODE_ENV=development
DATABASE_URL=postgresql://timetiles_user:timetiles_password@localhost:5432/timetiles
PAYLOAD_SECRET=dev-secret-change-in-production
LOG_LEVEL=debugProduction Settings (.env.production)
NODE_ENV=production
DATABASE_URL=postgresql://prod_user:strong_password@db.internal:5432/timetiles_prod
PAYLOAD_SECRET=<generate-with-openssl-rand-base64-32>
LOG_LEVEL=info
ENABLE_SECURITY_HEADERS=trueConfiguration Files
Next.js Configuration
The apps/web/next.config.mjs file contains:
- Standalone output for production
- Image optimization settings
- Security headers
- Webpack customizations
TypeScript Configuration
Strict mode is enabled across the monorepo with shared configs in packages/typescript-config/.
Database Configuration
PostgreSQL settings can be tuned via environment variables or directly:
-- For production workloads
ALTER SYSTEM SET shared_buffers = '2GB';
ALTER SYSTEM SET effective_cache_size = '6GB';
ALTER SYSTEM SET work_mem = '64MB';
ALTER SYSTEM SET maintenance_work_mem = '512MB';
-- Apply changes
SELECT pg_reload_conf();Validation
TimeTiles validates configuration on startup:
- Required variables: Checks for DATABASE_URL and PAYLOAD_SECRET
- Database connection: Verifies PostgreSQL is accessible
- PostGIS extension: Ensures spatial functions are available
Troubleshooting Configuration
Missing Environment Variables
# Check loaded variables
make dev
# Look for warnings about missing configurationInvalid Database URL
# Test connection
psql $DATABASE_URL -c "SELECT 1"Geocoding Issues
Check geocoding provider configuration in the admin panel at /admin/collections/geocoding-providers.
To test a provider’s API key directly:
# Test Google Maps API (replace YOUR_API_KEY with the key from admin panel)
curl "https://maps.googleapis.com/maps/api/geocode/json?address=Paris&key=YOUR_API_KEY"
# Test OpenCage API
curl "https://api.opencagedata.com/geocode/v1/json?q=Paris&key=YOUR_API_KEY"
# Test Nominatim (no key required)
curl "https://nominatim.openstreetmap.org/search?q=Paris&format=json"Next Steps
- Deploy to Production with your configuration
- Setup Monitoring for your instance
- Review Security Best Practices