Production readiness
A pre-launch checklist covering environment, database, search cluster, secrets, storage, email, billing, monitoring, backups, and smoke tests.
Production readiness
This page is the checklist to run before flipping traffic onto AACsearch in production. It is deliberately granular — checkboxes you can copy into a launch ticket. If you've already worked through Security overview and Operations, most items will be familiar; this is where they meet.
For the day-to-day operational picture once you're live, see Operations. For the security pre-launch checklist, see Security overview.
How to use this page
- Each section is a checklist for one production concern.
- An item that doesn't apply to your deployment can be marked N/A — but write down why, not "skipped".
- Two-person rule: every checkbox should be verified by someone other than the one who wrote it.
1. Environment
- Production deployment is on its own organization, not a project inside the staging org.
- Domain you'll call AACsearch from is set up (your API endpoint, your widget host).
-
NODE_ENV=productionin your application runtime. -
DATABASE_URLpoints at your production database (not staging)..env.localand.envagree on this. -
BETTER_AUTH_SECRETis set to a strong, unique value in production (32+ random bytes). -
NEXT_PUBLIC_*envs do not leak any non-public values. Audit them by searching your bundle. - CDN in front of your application is configured for the regions you serve.
- Reverse-proxy / load balancer terminates TLS 1.3.
- Health checks point at your application's
/healthendpoint, not AACsearch's.
2. Database
This is your application database, not ours. AACsearch's PostgreSQL is managed by us; this section is for the database that holds your source-of-truth product / content / customer data.
- Connection pool sized for your peak request rate (start with
max = (cpu cores × 4) + 1). - Backups configured and tested —
pg_dumpis not a backup strategy; use WAL archiving. - Restore tested from backup at least once, not just verified that backups exist.
- Replication lag is monitored (if you have replicas).
- Long-running query alert (e.g. > 30 s) wired into your paging.
- Index migration plan: schema changes are accompanied by a Prisma migration, not raw SQL drift.
- PII columns are encrypted at rest if your jurisdiction requires it.
3. Search cluster (AACsearch)
- Production project is separate from staging project (separate API keys, indexes, billing).
- Index schemas reviewed: every field that needs to be searched is in
query_by; every field that needs to filter isindex: true. -
default_sorting_fieldis set on indexes where order matters at query time. - Initial reindex completed and verified — see Reindexing.
- Doc count drift is below 5 % (green health badge).
- At least one negative test for tenant isolation passes — see Tenant isolation.
- Synonyms and curations applied to the production indexes.
- Webhooks (if used) point at production endpoints, not staging.
4. Secrets and API keys
- No
ss_search_…,ss_connector_…, orss_scoped_…value is committed in any repository. Search every repo your team owns. - Production API keys are different from development and staging keys.
- Browser-facing keys have
searchscope only and an origin allow-list — see Origin allow-list. - Server-side
ingestandadminkeys are stored in your secret manager (Vault, AWS Secrets Manager, Doppler), not env files committed anywhere. - Each service has its own key. Don't share one admin key across services.
- Key rotation calendar is set (90 days for admin keys, 30 days for browser keys is reasonable).
- 2FA is enforced for every member with
adminorownerrole. - If using SCIM, the SCIM bearer token is in your IdP's secret store — see SSO and SCIM.
5. Storage
This applies to S3 / object storage that your application uses, not AACsearch's internal S3.
- Production bucket(s) are separate from non-production. Cross-bucket reads are not granted.
- Bucket region matches your data residency requirement.
- Encryption at rest enabled (SSE-S3 or SSE-KMS).
- Versioning enabled if you do destructive writes.
- Lifecycle rules set: archive old objects to cheaper storage, expire after retention.
- CORS configured to your domains only (not
*). - Pre-signed URLs use HTTPS, are short-lived, and have minimum necessary permissions.
6. Email
If your application sends transactional or notification email through AACsearch (resets, alerts) or directly:
- SPF, DKIM, and DMARC records published on your sending domain.
- DMARC starts in
p=quarantineonly after ap=nonereporting period confirmed alignment. - Bounces and complaints are captured and processed (don't keep emailing dead addresses).
- Test email path from a real, non-developer mailbox before launch.
- Unsubscribe link in marketing email follows RFC 8058 (
List-Unsubscribeheader). - Transactional and marketing email use different sending domains or subdomains.
7. Billing
- Production payment method is on the production organization, not your personal card.
- Billing contact email is a shared inbox (
billing@yourcompany.com), not one person's. - Plan tier matches projected load with at least 30 % headroom for the first month.
- Quota alerts are enabled — see Rate limits and quotas.
- If you've set up wallet / overage bypass, the top-up threshold is documented.
- For Enterprise: contract, DPA, and any custom SLA are signed and filed.
8. Monitoring
- Each of the four signals is wired into your observability — see Monitoring: doc count drift, ingest lag, error rate, rate-limit 429s.
- Thresholds match the values in the Monitoring page (or are tighter).
- Alerts route to a paging tool with rotation, not just an email alias.
- Status page subscription is set up — see Status and incidents. Wire to your incident channel, not someone's inbox.
- Sentry (or equivalent) tagged with
requestId,orgId,indexId— see Observability. - A synthetic search runs from each region you serve every minute.
9. Backups and recovery
- You understand what AACsearch backs up and what you back up yourself.
- An export of your search indexes is scheduled on your side (NDJSON to your S3) — covers the "we want our own copy" requirement.
- Audit log export is scheduled — see Audit log export.
- Restore drill: at least one team member has practiced restoring from your own backups in the last 90 days. (Restoring AACsearch is our job; restoring your data is yours.)
- Disaster recovery runbook exists for your application — see DR recovery runbook for our side as a reference.
10. Launch smoke tests
Run all of these against production before opening traffic:
- Sign in to the dashboard as each role you have (owner, admin, member) and confirm correct view.
- Create a test document via your ingest path, then search for it.
- Delete the test document; confirm it disappears from search within 60 seconds.
- Trigger a search with a deliberately invalid filter and confirm the error is what you expect.
- Trigger a search that should return zero hits and confirm the empty-state UX.
- Trigger a search that should hit the rate limit; confirm your client backs off cleanly.
- Mint a scoped token, send a search with the user's tenant ID, confirm cross-tenant data is invisible — see Tenant isolation.
- If you have webhooks: trigger one event, confirm delivery in Webhooks → Deliveries.
- If you have SCIM: deactivate a test user in your IdP, confirm they lose access in AACsearch within the sync window.
After launch
The first 72 hours are the period where the production checklist meets reality. Watch the four signals from Monitoring closely; expect to learn that one threshold you set is too noisy and another is too quiet. Adjust during the first week, then leave them alone.
A weekly review of the audit log for the first month catches drift early. See Audit logs.
See also
- Security overview — production checklist
- Operations
- DR recovery runbook
- Enterprise procurement — additional pre-launch items for enterprise contracts