BYOC vs Managed vs Self-Hosted
RushDB offers three deployment models. This page explains the trade-offs so you can pick the right architecture from the start — or understand what's involved in moving between them.
Three deployment models
| Managed | BYOC | Self-Hosted | |
|---|---|---|---|
| Who runs RushDB | RushDB Cloud | RushDB Cloud | You |
| Your Neo4j instance | RushDB-managed | Yours (Aura or local) | Yours |
| Data residency | RushDB infrastructure | Your chosen region | Your infrastructure |
| Setup time | < 1 minute | ~15 minutes | 30–60 minutes |
| Ops burden | None | Minimal | Full |
| Raw Cypher access | ✗ | ✓ | ✓ |
| Custom embedding endpoint | ✗ | ✗ | ✓ |
| Managed billing | RushDB plans | RushDB plans + Neo4j costs | Infrastructure costs only |
| Backups | Automatic | Your responsibility | Your responsibility |
| SLA / uptime | RushDB SLA | RushDB SLA (RushDB layer) | DIY |
| Compliance (SOC 2, HIPAA) | Contact sales | Achievable | Achievable |
When to choose each
Managed — start here
Choose Managed when:
- You need to be working in minutes with no infrastructure setup.
- Your data residency and compliance requirements are flexible.
- You'd rather not think about Neo4j capacity planning.
- You're prototyping, running a hobby project, or in early-stage.
- Python
- TypeScript
- shell
from rushdb import RushDB
db = RushDB("rbk_xxxxxxxx")
// Nothing to configure — just use the cloud API key
import RushDB from '@rushdb/javascript-sdk'
const db = new RushDB('rbk_xxxxxxxx')
# All API calls use the cloud API key directly
curl -X POST https://api.rushdb.com/api/v1/records/search \
-H "Authorization: Bearer rbk_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"labels":["TEST"]}'
BYOC — bring your own Neo4j
Choose BYOC when:
- You already have a Neo4j Aura instance (or plan to).
- You need raw Cypher access for reporting or migrations.
- You want your graph data to stay within your cloud account or region.
- You want RushDB's API layer managed for you but want control over the graph store.
BYOC gives you a RushDB project that connects to your Neo4j credentials. See Connect an Aura Instance for the full setup guide.
- Python
- TypeScript
from rushdb import RushDB
db = RushDB("rbk_your_byoc_project_key")
// Same SDK interface — BYOC is transparent to application code
import RushDB from '@rushdb/javascript-sdk'
const db = new RushDB('rbk_your_byoc_project_key')
Feature unlocked — raw Cypher:
- Python
- TypeScript
- shell
result = db.query.raw("MATCH (n) RETURN count(n) AS total")
print(result)
const result = await db.query.raw('MATCH (n) RETURN count(n) AS total')
console.log(result)
curl -X POST https://api.rushdb.com/api/v1/query/raw \
-H "Authorization: Bearer rbk_your_byoc_project_key" \
-H "Content-Type: application/json" \
-d '{"query": "MATCH (n) RETURN count(n) AS total"}'
Self-Hosted — full control
Choose Self-Hosted when:
- Your data must not leave your own infrastructure.
- You need custom embedding endpoints (open-source models, private model servers).
- You want to customize deployment topology (multi-region, air-gapped, private VPC).
- Regulatory requirements mandate on-premises hosting.
See the Deployment guide for the complete Docker Compose walkthrough.
- Python
- TypeScript
- shell
import os
from rushdb import RushDB
db = RushDB(
os.environ["RUSHDB_API_KEY"],
base_url=os.environ["RUSHDB_API_URL"] # points to your own instance
)
import RushDB from '@rushdb/javascript-sdk'
const db = new RushDB(
process.env.RUSHDB_API_KEY,
{ url: process.env.RUSHDB_API_URL } // points to your own instance
)
# Point requests at your self-hosted instance
export BASE="https://rushdb.your-company.com/api/v1"
export TOKEN="your_self_hosted_api_key"
curl -X POST "$BASE/records/search" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"labels":["TEST"]}'
Feature gate reference
The following features are gated by deployment model:
| Feature | Managed | BYOC | Self-Hosted |
|---|---|---|---|
POST /api/v1/query/raw (raw Cypher) | ✗ | ✓ | ✓ |
| Custom embedding base URL | ✗ | ✗ | ✓ |
| External embedding indexes (BYOV) | ✓ | ✓ | ✓ |
| Dashboard access | ✓ | ✓ | ✓ |
| API key management | ✓ | ✓ | ✓ |
| Rate limiter configuration | ✗ | ✗ | ✓ |
Migrating between models
Managed → BYOC
Managed and BYOC share the same RushDB API layer. There is no direct data export between Neo4j instances since BYOC uses your Neo4j that you provision separately. The migration flow is:
1. Document your data shape
Use getOntologyMarkdown() to capture your record labels, property names, and relationship types before migrating:
- Python
- TypeScript
ontology = db.get_ontology_markdown()
print(ontology)
const ontology = await db.getOntologyMarkdown()
// Save this as a snapshot of your schema
console.log(ontology)
2. Export your data
Use records.find() with pagination to export records by label:
- Python
- TypeScript
- shell
PAGE_SIZE = 500
skip = 0
all_records = []
while True:
result = db.records.find(
labels=['Product'],
skip=skip,
limit=PAGE_SIZE
)
all_records.extend(result.data)
if len(all_records) >= result.total:
break
skip += PAGE_SIZE
const PAGE_SIZE = 500
let skip = 0
const allRecords = []
while (true) {
const { data, total } = await db.records.find({
labels: ['Product'],
skip,
limit: PAGE_SIZE
})
allRecords.push(...data)
if (allRecords.length >= total) break
skip += PAGE_SIZE
}
// Serialize for re-import
const payload = allRecords.map(r => ({
__label: 'Product',
...r
}))
BASE="https://api.rushdb.com/api/v1"
TOKEN="RUSHDB_API_KEY"
H='Content-Type: application/json'
# Paginated export
SKIP=0
while true; do
PAGE=$(curl -s -X POST "$BASE/records/search" \
-H "$H" -H "Authorization: Bearer $TOKEN" \
-d "{\"labels\":[\"Product\"],\"skip\":$SKIP,\"limit\":500}")
COUNT=$(echo "$PAGE" | jq '.data | length')
echo "$PAGE" | jq '.data[]' >> exported_products.jsonl
[[ $COUNT -lt 500 ]] && break
SKIP=$((SKIP + 500))
done
3. Create a BYOC project
In the RushDB Dashboard, create a new project using "Use my own Neo4j instance" and follow the BYOC setup guide.
4. Re-import into the BYOC project
Point your SDK at the new API key and re-ingest:
- Python
- TypeScript
- shell
byoc_db = RushDB('rbk_byoc_project_key')
byoc_db.records.import_json(
label='Product',
data=payload
)
const byocDb = new RushDB('rbk_byoc_project_key')
await byocDb.records.importJson({
label: 'Product',
data: payload
})
BYOC_TOKEN="rbk_byoc_project_key"
curl -s -X POST "$BASE/records/import" \
-H "$H" -H "Authorization: Bearer $BYOC_TOKEN" \
-d '{"label":"Product","data":[...]}'
BYOC / Managed → Self-Hosted
Self-hosted uses the same REST API surface as the cloud. The migration steps are:
- Deploy your self-hosted instance with
RUSHDB_SELF_HOSTED=true. - Create a project and API key via the self-hosted dashboard at
http://your-host:3000. - Export records from the cloud using the pagination pattern above.
- Point the SDK at your self-hosted URL and re-import.
- Python
- TypeScript
- shell
import os
from rushdb import RushDB
self_hosted_db = RushDB(
os.environ["SELFHOSTED_API_KEY"],
base_url="https://rushdb.your-company.com/api/v1"
)
const selfHostedDb = new RushDB(
process.env.SELFHOSTED_API_KEY,
{ url: 'https://rushdb.your-company.com/api/v1' }
)
export BASE="https://rushdb.your-company.com/api/v1"
export TOKEN="your_self_hosted_api_key"
curl -X POST "$BASE/records/search" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"labels":["Product"]}'
Self-Hosted → Managed
The same export/re-import pattern applies. In addition, you can leverage raw Cypher on self-hosted to bulk-export complex relationship graphs before re-ingesting them via importJson on managed.
Quick decision tree
Do you need data to stay on your own infrastructure?
└─ Yes → Self-Hosted
Do you already have a Neo4j instance, or need raw Cypher?
└─ Yes → BYOC
Starting fresh with no ops requirements?
└─ Yes → Managed
Next steps
- Get started with Managed — Quickstart
- Set up BYOC — Connect an Aura Instance
- Deploy self-hosted — Deployment
- Manage projects post-deploy — Self-Hosted Project Setup