Configuration
TimeTiles uses three configuration layers, each suited for different types of settings:
| Layer | Format | What goes here | Changed by |
|---|---|---|---|
| Environment variables | .env | Secrets, infrastructure, paths | Operator (deploy-time) |
| Config file | config/timetiles.yml | Rate limits, quotas, batch sizes | Operator (deploy-time, restart) |
| Admin dashboard | Database (Payload CMS) | Feature flags, geocoding, branding | Admin (runtime UI) |
The config file and all environment variables (except DATABASE_URL, PAYLOAD_SECRET) are optional — sensible defaults are applied automatically.
Environment Variables
Required
DATABASE_URL=postgresql://user:password@localhost:5432/timetiles
PAYLOAD_SECRET=your-secret-key # openssl rand -base64 32
NEXT_PUBLIC_PAYLOAD_URL=https://your-domain.comInfrastructure
NODE_ENV=production # development, production, test
NEXT_PUBLIC_SITE_URL=https://... # If different from NEXT_PUBLIC_PAYLOAD_URL
DEFAULT_LOCALE=en # en or deFile Paths
UPLOAD_DIR=uploads # Base directory (subfolders: /media, /import-files)
UPLOAD_TEMP_DIR=/tmp # Temporary files during upload
DATA_EXPORT_DIR=.exports # User data export outputLogging
LOG_LEVEL=info # trace, debug, info, warn, error, fatal, silent
LOG_FILE=/var/log/timetiles/app.log # Optional file loggingEmail (SMTP)
Without SMTP settings, emails are logged to console in development (via ethereal.email).
EMAIL_SMTP_HOST=smtp.example.com
EMAIL_SMTP_PORT=587
EMAIL_SMTP_USER=your-user
EMAIL_SMTP_PASS=your-password
EMAIL_FROM_ADDRESS=noreply@timetiles.io
EMAIL_FROM_NAME=TimeTilesSecurity
SSRF_DNS_CHECK=true # DNS validation for SSRF protection (recommended in production)
ALLOW_PRIVATE_URLS=true # Allow RFC 1918 addresses (development only!)Scraper Integration
Optional — only needed if running the TimeScrape runner.
SCRAPER_RUNNER_URL=http://localhost:4000
SCRAPER_API_KEY=your-api-key-min-16-charsConfig File (timetiles.yml)
For structured settings that don’t fit flat environment variables — rate limits with multiple time windows, per-trust-level quotas, cache tuning.
Copy the example and customize:
cp config/timetiles.example.yml config/timetiles.ymlThe file is optional. If absent, all defaults apply. Changes require a server restart.
In Docker, the config directory is mounted read-only into all containers via CONFIG_DIR in your .env.production:
CONFIG_DIR=./configRate Limits
Per-endpoint rate limiting with burst, hourly, and daily windows. windowMs is in milliseconds.
rateLimits:
FILE_UPLOAD:
windows:
- { limit: 1, windowMs: 5000, name: burst } # 1 per 5 seconds
- { limit: 5, windowMs: 3600000, name: hourly } # 5 per hour
- { limit: 20, windowMs: 86400000, name: daily } # 20 per day
API_GENERAL:
windows:
- { limit: 5, windowMs: 1000, name: burst }
- { limit: 50, windowMs: 3600000, name: hourly }
REGISTRATION:
windows:
- { limit: 3, windowMs: 60000, name: burst }
- { limit: 10, windowMs: 3600000, name: hourly }
- { limit: 20, windowMs: 86400000, name: daily }Available endpoint names: FILE_UPLOAD, PROGRESS_CHECK, IMPORT_RETRY, ADMIN_IMPORT_RESET, RETRY_RECOMMENDATIONS, API_GENERAL, WEBHOOK_TRIGGER, NEWSLETTER_SUBSCRIBE, PASSWORD_CHANGE, EMAIL_CHANGE, ACCOUNT_DELETION, DELETION_PASSWORD_ATTEMPTS, DATA_EXPORT, REGISTRATION.
Quotas by Trust Level
Override the default quotas per trust level. Use -1 for unlimited. You only need to include the values you want to change.
quotas:
2: # Regular users
maxEventsPerImport: 20000
maxTotalEvents: 100000
3: # Trusted users
maxFileUploadsPerDay: 100Trust levels: 0 = Untrusted, 1 = Basic, 2 = Regular, 3 = Trusted, 4 = Power User, 5 = Unlimited. See Usage Limits for the full default table.
Trust-Level Rate Limits
Per-trust-level rate limits for file uploads and API access:
trustLevelRateLimits:
0: # Untrusted — very restrictive
FILE_UPLOAD:
windows:
- { limit: 1, windowMs: 60000, name: burst }
- { limit: 1, windowMs: 3600000, name: hourly }
API_GENERAL:
windows:
- { limit: 1, windowMs: 1000, name: burst }
- { limit: 10, windowMs: 3600000, name: hourly }Batch Sizes
Tune the import pipeline’s processing batch sizes:
batchSizes:
duplicateAnalysis: 5000
schemaDetection: 10000
eventCreation: 1000
databaseChunk: 1000Cache
URL fetch cache for scheduled imports:
cache:
urlFetch:
dir: /tmp/url-fetch-cache
maxSizeBytes: 104857600 # 100 MB
defaultTtlSeconds: 3600 # 1 hour
maxTtlSeconds: 2592000 # 30 days
respectCacheControl: true # Honor RFC 7234 headersAccount Settings
account:
deletionGracePeriodDays: 30Admin Dashboard Settings
These are configured at runtime through the admin UI — no restart needed.
Feature Flags
Configure at /dashboard/globals/settings under “Feature Flags”:
| Flag | Default | Description |
|---|---|---|
| Allow Private Imports | On | Users can create private imports |
| Enable Scheduled Ingests | On | Automated URL-based imports |
| Enable Public Registration | On | Self-registration for new users |
| Enable Event Creation | On | Events can be created via import or API |
| Enable Dataset Creation | On | Users can create new datasets |
| Enable Import Creation | On | Users can start new imports |
| Enable Scheduled Job Execution | On | Scheduled imports run automatically |
| Enable URL Fetch Caching | On | Cache URL fetches to reduce external requests |
| Enable Scrapers | Off | Scraper repos and execution (trust level 3+) |
Geocoding
Configure providers at /dashboard/collections/geocoding-providers:
| Provider | API Key | Notes |
|---|---|---|
| Nominatim | No | Free, based on OpenStreetMap. Enabled by default |
| Google Maps | Yes | Most accurate. Configure key in dashboard |
| OpenCage | Yes | Good international coverage |
Global geocoding settings at /dashboard/globals/settings:
- Enable/disable geocoding globally
- Toggle provider fallback
- Selection strategy (priority-based or tag-based)
- Cache TTL
Branding & Content
- Branding (
/dashboard/globals/branding) — site name, description, logos, favicon - Main Menu (
/dashboard/globals/main-menu) — navigation links - Footer (
/dashboard/globals/footer) — tagline, social links, columns, copyright - Newsletter (
/dashboard/globals/settings) — external newsletter service URL
Roles
| Role | Permissions |
|---|---|
| User | Own catalogs, datasets, and imports |
| Editor | User + branding, advanced dataset config |
| Admin | Full access: user management, settings, feature flags |
Next Steps
- Deploy to production
- Set up backups
- Customize the UI with themes and branding
- Configure usage limits and trust levels