FAQ
Common questions about j17. Not finding what you need? Email support@j17.dev
Getting started
How do I get an API key?
Sign up at j17.dev, create an instance, then generate keys in Settings -> API Keys.
Is there a free tier?
Yes. 1,000 events/month, 1GB storage, 100 req/min. No credit card required.
What's the difference between staging and production?
Separate environments with isolated data and API keys. Test freely in staging without affecting production.
Can I use j17 from the browser?
Yes. j17 supports CORS. Use read-only API keys for client-side code, or proxy writes through your backend.
Events and aggregates
Can I delete an event?
No. Events are immutable. Write a compensating event instead (e.g., order_was_cancelled).
How many events can an aggregate have?
Soft limit of 10,000 events per aggregate. After that, use checkpoints or consider if your aggregate boundaries are right.
What's a good aggregate size?
Most aggregates have 10-100 events. Hundreds is fine. Thousands suggests you need checkpoints or a different model.
Can I query across aggregates?
Not directly. Use projections for multi-aggregate views, or export to a data warehouse for analytics.
How do I list all users?
Event sourcing isn't table scanning. Maintain a projection with user IDs, or track IDs in your database when you create them.
Spec and handlers
Do I need to redeploy when I change the spec?
No. Upload the new spec via API or dashboard. Changes apply immediately.
Can I have multiple event types with the same name?
No. Event types are unique within an aggregate type. user.was_created and order.was_created are fine.
What happens to old events when I change a handler?
Nothing. Old events stay as-is. New events use the new handler. If you need to migrate, consider upcasters (store handler version in event metadata).
Can I use TypeScript/JavaScript for handlers?
Not directly. Tick's 17 declarative operations cover most cases without code. For complex logic that Tick can't express, that's a sign to rethink your event modeling.
How do I validate complex business rules?
Either: 1. Validate client-side before writing (for UX) 2. Use Tick conditionals for simple rules 3. Accept the event and handle invalid states via implications 4. Use external validation in your backend before posting to j17
Performance
How fast is j17?
- Event write: ~5ms
- Aggregate read: ~2ms (small), ~10ms (medium), ~50ms (large)
- Tick handler: 300k+ ops/sec per core
When should I use caching?
For aggregates queried > 100 times/minute. Start without caching, add when needed.
What are the rate limits?
- 500 requests/minute per API key
- 2,000 requests/minute per IP address
Can I use j17 for real-time applications?
Use polling. SSE/WebSocket subscriptions are not yet available.
Data and storage
Where is my data stored?
EU (Germany) by default. US and Asia regions coming soon. Contact support to request a region.
Is my data encrypted?
Yes. Encrypted at rest and in transit. TLS 1.3 for all connections.
Can I export my data?
Yes. Use the Admin API to export aggregates or events as JSON/NDJSON.
What happens if I exceed my plan limits?
We don't throttle hard -- your app keeps working. You'll get an email notification. Upgrade or contact us within 48 hours.
How long do you keep my data?
Forever, unless you delete it. We don't auto-purge old events.
Safety limits
j17 enforces safety limits on spec complexity:
- Handler depth: max 5 levels of nesting
- Handler operations: max 100 total operations per event type
These exist to prevent accidentally creating specs that are expensive to evaluate.
Security
Can I rotate API keys?
Yes. Create new keys, update your services, delete old keys. Old requests fail immediately.
Are webhooks signed?
Yes. j17 signs webhooks with HMAC-SHA256. Verify the signature to ensure authenticity.
Can j17 see my data?
Technically yes -- we store it. But we: - Don't access it unless debugging a support issue (with permission) - Don't sell or share it
Is j17 SOC 2 compliant?
In progress. Contact sales@j17.dev for compliance questions.
Pricing and billing
How is pricing calculated?
Per day based on: - Events written - Storage used - API calls made
See pricing page for tiers.
Do you charge for reads?
Yes, but minimally. Reads are 1/10th the cost of writes.
What counts as an "event"?
Every POST to /{type}/{id}/{event} counts as one event, regardless of size.
Do scheduled/implied events count?
Yes. Any event written to your instance counts toward your quota.
Can I set billing alerts?
Yes. Configure alerts at 50%, 80%, and 100% of your plan limits.
Troubleshooting
I get 409 Conflict. What does that mean?
Optimistic concurrency check failed. Someone else wrote to the aggregate between your GET and POST. Refetch and retry.
I get 422 Validation failed. How do I fix it?
Your event data doesn't match the schema. Check the details field in the error response -- it tells you exactly what failed.
Events aren't triggering implications.
Check:
1. Is the implication defined in your spec?
2. Does the when condition evaluate to true?
3. Check /admin/implications/failed for errors
My aggregate loads slowly.
- Enable caching for frequently-read aggregates
- Create a checkpoint for large aggregates
- Check if you're including events unnecessarily
I'm rate limited.
Check your current usage. API keys are limited to 500 req/min and IPs to 2,000 req/min. Implement client-side backoff with exponential retry.
Comparisons
How is j17 different from Postgres?
Postgres stores current state. j17 stores history and derives state. Trade-off: you get audit trails and temporal queries, you lose simple SQL.
vs Redis?
Redis is a cache. j17 is persistent storage with cache characteristics. Don't use Redis as your primary event store.
vs Kafka?
Kafka is a message bus. j17 is a database. Kafka doesn't compute aggregates or validate schemas.
vs EventStoreDB/KurrentDB?
j17 is managed, cheaper, and simpler. EventStoreDB is more powerful (projections, complex queries) but requires expertise and budget.
vs Supabase/Firebase?
Those are general-purpose databases. j17 is purpose-built for event sourcing. Use them for CRUD, j17 for audit trails and temporal data.
Advanced
Can I self-host j17?
Not yet. We're focused on the managed service. Enterprise on-prem may come later.
Do you support multi-region?
Not yet. Single region per instance. Multi-region replication is on the roadmap.
Can I write events in a transaction?
Yes. Use batch writes to post multiple events to the same aggregate atomically. For cross-aggregate atomicity, use implications.
How do I migrate from another database?
- Identify events in your existing data (every UPDATE is a potential event)
- Write a migration script that POSTs events to j17
- Dual-write for a period (write to both old and new)
- Cut over reads to j17
- Stop writing to old database
See our migration guide for details.
Can I use j17 with AI/LLMs?
Yes. j17 is AI-friendly: - Spec is JSON (LLMs understand it) - API is HTTP (universal) - Entire backend fits in a context window
Load our docs into Claude/Cursor and describe your app. The AI will generate your spec.
Getting help
Documentation: docs.j17.dev Email: support@j17.dev Status: status.j17.dev
We typically respond within 24 hours. Enterprise customers get priority support with 4-hour SLA.