| Mode | Mock | Deploy |
|---|---|---|
| MySQL | Off | |
| PostgreSQL | Off | |
| MySQL | On | |
| PostgreSQL | On |
Set env variables by scenario (one scenario per row):
| Scenario | Required envs (with defaults/examples) |
|---|---|
| MySQL (Mock Off) | AIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=mysqlAIMETER_DATABASE_CONNECTION=mysql://USER:PASSWORD@HOST:3306/DATABASE |
| PostgreSQL (Mock Off) | AIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=postgresAIMETER_DATABASE_CONNECTION=postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require |
| MySQL (Mock On) | AIMETER_MOCK_ENABLED=trueAIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=mysqlAIMETER_DATABASE_CONNECTION=mysql://USER:PASSWORD@HOST:3306/DATABASE |
| PostgreSQL (Mock On) | AIMETER_MOCK_ENABLED=trueAIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=postgresAIMETER_DATABASE_CONNECTION=postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require |
Database configuration is mandatory.
| Mode | Required envs (with examples) |
|---|---|
| MySQL | AIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=mysqlAIMETER_DATABASE_CONNECTION=mysql://USER:PASSWORD@HOST:3306/DATABASE |
| PostgreSQL | AIMETER_RUNTIME_MODE=serverlessAIMETER_SERVER_PROTOCOL=httpsAIMETER_DATABASE_ENGINE=postgresAIMETER_DATABASE_CONNECTION=postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require |
Mock-only additional env:
AIMETER_MOCK_ENABLED=true
Optional integration secrets: AIMETER_CRON_SECRET, AIMETER_ENDPOINT_SECRET
- In database mode, these values are used only for first-time initialization (then managed in DB).
Secrets can be generated with:
openssl rand -hex 16Important:
- For MySQL/PostgreSQL, the target database must be created before deployment.
- AIMeter initializes required tables only (
providers,usage_records,settings,audit_logs). - AIMeter does not create the database itself.
mysql://USER:PASSWORD@HOST:3306/DATABASE
If SSL is required, use ssl in the DSN query:
mysql://USER:PASSWORD@HOST:3306/DATABASE?ssl={"rejectUnauthorized":true}
If your MySQL uses a self-signed certificate, use:
mysql://USER:PASSWORD@HOST:3306/DATABASE?ssl={"rejectUnauthorized":false}
postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require
If your PostgreSQL uses a self-signed certificate, use:
postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=no-verify
Vercel Cron cannot send custom headers, but AIMeter's job endpoint requires x-aimeter-cron-secret. Use an external service instead:
Recommended schedule: run every 5 minutes. Reason: provider refresh uses a minimum granularity of 5 minutes. Different providers can have different refresh intervals, and each API call every 5 minutes will evaluate all providers' refresh windows.
Example:
- Provider A refresh interval = 5 minutes
- Provider B refresh interval = 30 minutes
- In 30 minutes, the endpoint runs 6 times
- A can refresh on every run
- B may refresh only on the 6th run when its 30-minute window is reached
- Create an account at cron-job.org
- Create a new cron job:
- URL:
https://your-app.vercel.app/api/system/jobs/refresh - Method:
POST - Header:
x-aimeter-cron-secret: <your AIMETER_CRON_SECRET value> - Schedule: every 5 minutes
- URL:
Add .github/workflows/cron.yml to your repository:
name: AIMeter Cron
on:
schedule:
- cron: '*/5 * * * *' # every 5 minutes
workflow_dispatch:
jobs:
refresh:
runs-on: ubuntu-latest
steps:
- name: Trigger usage refresh
run: |
curl -X POST https://your-app.vercel.app/api/system/jobs/refresh \
-H "x-aimeter-cron-secret: ${{ secrets.AIMETER_CRON_SECRET }}"Add AIMETER_CRON_SECRET as a GitHub Actions secret in your repository settings.
| Feature | Status |
|---|---|
| SQLite persistent storage | Not supported on Vercel serverless filesystem |
| In-process scheduler | Disabled (AIMETER_RUNTIME_MODE=serverless) |
| In-memory rate limiting | Resets on cold start |
| Static files | Served from Vercel CDN (dist/) |
window.__AIMETER_ENTRY__ injection |
Not used — frontend falls back to GET /api/entry-context |
After deploying:
- Health check:
GET https://your-app.vercel.app/api/health→{"status":"ok"} - SPA routing: Navigate to any deep URL — page should load correctly
- Admin path: complete bootstrap first, then use the generated/stored admin path
- Local test (Postgres):
AIMETER_DATABASE_ENGINE=postgres AIMETER_DATABASE_CONNECTION=<dsn> vercel dev - Local test (MySQL):
AIMETER_DATABASE_ENGINE=mysql AIMETER_DATABASE_CONNECTION=<dsn> vercel dev