<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<p>This comprehensive guide covers all aspects of migrating to and within Geode: version upgrades, data migration from other databases, backup and restore procedures, zero-downtime strategies, and best practices for production environments.</p>
<h3 id="overview" class="position-relative d-flex align-items-center group">
<span>Overview</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="overview"
aria-haspopup="dialog"
aria-label="Share link: Overview">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Geode provides multiple migration paths depending on your source system and requirements:</p>
<ul>
<li><strong>Version Upgrades</strong>: Migrate between Geode versions with backward compatibility</li>
<li><strong>Database Migrations</strong>: Move data from Neo4j, JanusGraph, or other graph databases</li>
<li><strong>Backup & Restore</strong>: Use S3-compatible cloud storage for disaster recovery</li>
<li><strong>Zero-Downtime Migrations</strong>: Maintain service availability during upgrades</li>
<li><strong>Schema Evolution</strong>: Safely modify schemas in production systems</li>
</ul>
<h3 id="version-upgrade-guide" class="position-relative d-flex align-items-center group">
<span>Version Upgrade Guide</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="version-upgrade-guide"
aria-haspopup="dialog"
aria-label="Share link: Version Upgrade Guide">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="current-version-status" class="position-relative d-flex align-items-center group">
<span>Current Version Status</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="current-version-status"
aria-haspopup="dialog"
aria-label="Share link: Current Version Status">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Geode <strong>v0.2.18</strong></strong> (<strong>March 30, 2026</strong>) - Current stable release</p>
<ul>
<li>100% GQL compliance (ISO/IEC 39075:2024)</li>
<li>Current stable line for production deployments</li>
<li>Follow the release notes for post-<code>v0.2.18</code> <code>main</code> fixes before adopting unreleased builds</li>
</ul>
<h4 id="pre-upgrade-checklist" class="position-relative d-flex align-items-center group">
<span>Pre-Upgrade Checklist</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pre-upgrade-checklist"
aria-haspopup="dialog"
aria-label="Share link: Pre-Upgrade Checklist">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Before upgrading any Geode instance, complete this checklist:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1. Check current version</span>
</span></span><span class="line"><span class="cl">geode --version
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Create full backup</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://my-bucket/backups --mode full
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Verify backup integrity</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://my-bucket/backups --list
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. Document current configuration</span>
</span></span><span class="line"><span class="cl">cp /etc/geode/geode.yaml /etc/geode/geode.yaml.backup
</span></span><span class="line"><span class="cl">env <span class="p">|</span> grep GEODE_ > geode-env.backup
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. Test queries in new version (staging environment first)</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"MATCH (n) RETURN count(n)"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 6. Review release notes for breaking changes</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Check: https://geodedb.com/docs/release-notes/</span>
</span></span></code></pre></div>
<h4 id="in-place-upgrade-procedure" class="position-relative d-flex align-items-center group">
<span>In-Place Upgrade Procedure</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="in-place-upgrade-procedure"
aria-haspopup="dialog"
aria-label="Share link: In-Place Upgrade Procedure">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Upgrade existing Geode installation without data migration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1. Stop current server gracefully</span>
</span></span><span class="line"><span class="cl">systemctl stop geode
</span></span><span class="line"><span class="cl"><span class="c1"># Or: pkill -TERM geode</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Backup data directory</span>
</span></span><span class="line"><span class="cl">tar -czf /backup/geode-data-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span>.tar.gz /var/lib/geode/data
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Install new version (build from source)</span>
</span></span><span class="line"><span class="cl">git clone https://github.com/codeprosorg/geode /tmp/geode-upgrade
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /tmp/geode-upgrade
</span></span><span class="line"><span class="cl">make build
</span></span><span class="line"><span class="cl">install -m <span class="m">0755</span> ./zig-out/bin/geode /usr/local/bin/geode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. Verify new version</span>
</span></span><span class="line"><span class="cl">geode --version
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. Start server with existing data</span>
</span></span><span class="line"><span class="cl">systemctl start geode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 6. Verify server health</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"RETURN 1 AS health_check"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 7. Monitor logs for errors</span>
</span></span><span class="line"><span class="cl">journalctl -u geode -f
</span></span></code></pre></div>
<h4 id="rolling-upgrade-distributed-clusters" class="position-relative d-flex align-items-center group">
<span>Rolling Upgrade (Distributed Clusters)</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="rolling-upgrade-distributed-clusters"
aria-haspopup="dialog"
aria-label="Share link: Rolling Upgrade (Distributed Clusters)">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Upgrade cluster nodes with zero downtime:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Build new version locally (run once)</span>
</span></span><span class="line"><span class="cl">git clone https://github.com/codeprosorg/geode /tmp/geode-upgrade
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /tmp/geode-upgrade
</span></span><span class="line"><span class="cl">make build
</span></span><span class="line"><span class="cl"><span class="nv">GEODE_BIN</span><span class="o">=</span>/tmp/geode-upgrade/zig-out/bin/geode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 1. Upgrade secondary nodes first (one at a time)</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> node in node2 node3 node4<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">"Upgrading </span><span class="nv">$node</span><span class="s2">..."</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Stop node</span>
</span></span><span class="line"><span class="cl"> ssh <span class="nv">$node</span> <span class="s2">"systemctl stop geode"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Install new version</span>
</span></span><span class="line"><span class="cl"> scp <span class="s2">"</span><span class="nv">$GEODE_BIN</span><span class="s2">"</span> <span class="s2">"</span><span class="nv">$node</span><span class="s2">:/usr/local/bin/geode"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Start node</span>
</span></span><span class="line"><span class="cl"> ssh <span class="nv">$node</span> <span class="s2">"systemctl start geode"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Verify health</span>
</span></span><span class="line"><span class="cl"> ssh <span class="nv">$node</span> <span class="s2">"geode query 'RETURN 1 AS health'"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Wait for node to stabilize</span>
</span></span><span class="line"><span class="cl"> sleep <span class="m">30</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Upgrade primary node last</span>
</span></span><span class="line"><span class="cl">ssh node1 <span class="s2">"systemctl stop geode"</span>
</span></span><span class="line"><span class="cl">scp <span class="s2">"</span><span class="nv">$GEODE_BIN</span><span class="s2">"</span> <span class="s2">"node1:/usr/local/bin/geode"</span>
</span></span><span class="line"><span class="cl">ssh node1 <span class="s2">"systemctl start geode"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Verify cluster health</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"MATCH (n) RETURN count(n)"</span>
</span></span></code></pre></div>
<h4 id="configuration-migration" class="position-relative d-flex align-items-center group">
<span>Configuration Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="configuration-migration"
aria-haspopup="dialog"
aria-label="Share link: Configuration Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Migrate configuration between versions:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># Old configuration (v0.1.x)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">server</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">listen</span><span class="p">:</span><span class="w"> </span><span class="s1">'0.0.0.0:3141'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">data_dir</span><span class="p">:</span><span class="w"> </span><span class="s1">'/var/lib/geode'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># New configuration (v0.1.x) - backward compatible</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">server</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">listen</span><span class="p">:</span><span class="w"> </span><span class="s1">'0.0.0.0:3141'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">data_dir</span><span class="p">:</span><span class="w"> </span><span class="s1">'/var/lib/geode'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">max_connections</span><span class="p">:</span><span class="w"> </span><span class="m">50000</span><span class="w"> </span><span class="c"># New option</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">cert</span><span class="p">:</span><span class="w"> </span><span class="s1">'/etc/letsencrypt/live/geode.example.com/fullchain.pem'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="s1">'/etc/letsencrypt/live/geode.example.com/privkey.pem'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">auto_generate: false # New</span><span class="p">:</span><span class="w"> </span><span class="l">secure-by-default</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">security</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">auth_enabled: true # New</span><span class="p">:</span><span class="w"> </span><span class="l">enabled-by-default (was optional)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">storage</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">page_size</span><span class="p">:</span><span class="w"> </span><span class="m">8192</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">cache_size</span><span class="p">:</span><span class="w"> </span><span class="s1">'1GB'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">tde_enabled: true # New</span><span class="p">:</span><span class="w"> </span><span class="l">transparent data encryption</span><span class="w">
</span></span></span></code></pre></div><p><strong>Breaking Changes (v0.1.x → v0.1.x)</strong>:</p>
<ul>
<li>Authentication now <strong>enabled by default</strong> (was optional)</li>
<li>TLS auto-generation <strong>disabled by default</strong> (use proper certificates)</li>
<li>Hardcoded credentials removed (use environment variables)</li>
</ul>
<h3 id="migrating-from-other-graph-databases" class="position-relative d-flex align-items-center group">
<span>Migrating from Other Graph Databases</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="migrating-from-other-graph-databases"
aria-haspopup="dialog"
aria-label="Share link: Migrating from Other Graph Databases">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="neo4j-to-geode-migration" class="position-relative d-flex align-items-center group">
<span>Neo4j to Geode Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="neo4j-to-geode-migration"
aria-haspopup="dialog"
aria-label="Share link: Neo4j to Geode Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Migrate data from Neo4j to Geode using export/import strategy:</p>
<h5 id="step-1-export-from-neo4j" class="position-relative d-flex align-items-center group">
<span>Step 1: Export from Neo4j</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-1-export-from-neo4j"
aria-haspopup="dialog"
aria-label="Share link: Step 1: Export from Neo4j">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="o">//</span> <span class="n">Export</span> <span class="n">Neo4j</span> <span class="n">data</span> <span class="n">to</span> <span class="n">CSV</span>
</span></span><span class="line"><span class="cl"><span class="n">CALL</span> <span class="n">apoc</span><span class="o">.</span><span class="k">export</span><span class="o">.</span><span class="n">csv</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="s2">"neo4j-export.csv"</span><span class="p">,</span> <span class="p">{});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">//</span> <span class="n">Or</span> <span class="n">use</span> <span class="n">neo4j</span><span class="o">-</span><span class="n">admin</span> <span class="n">dump</span>
</span></span><span class="line"><span class="cl"><span class="n">neo4j</span><span class="o">-</span><span class="n">admin</span> <span class="n">database</span> <span class="n">dump</span> <span class="n">neo4j</span> <span class="o">--</span><span class="n">to</span><span class="o">=/</span><span class="n">backups</span><span class="o">/</span><span class="n">neo4j</span><span class="o">.</span><span class="n">dump</span>
</span></span></code></pre></div>
<h5 id="step-2-convert-cypher-to-gql" class="position-relative d-flex align-items-center group">
<span>Step 2: Convert Cypher to GQL</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-2-convert-cypher-to-gql"
aria-haspopup="dialog"
aria-label="Share link: Step 2: Convert Cypher to GQL">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><p>Neo4j uses Cypher; Geode uses ISO GQL (mostly compatible):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Neo4j</span><span class="w"> </span><span class="py">Cypher</span><span class="w"> </span><span class="p">(</span><span class="py">mostly</span><span class="w"> </span><span class="py">compatible</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">alice</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Alice</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">30</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">bob</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Bob</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">25</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">alice</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="w"> </span><span class="p">{</span><span class="py">since</span><span class="p">:</span><span class="w"> </span><span class="nc">2020</span><span class="p">}]</span><span class="err">-></span><span class="p">(</span><span class="py">bob</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span><span class="p">(</span><span class="py">identical</span><span class="w"> </span><span class="py">syntax</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">basic</span><span class="w"> </span><span class="py">operations</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">alice</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Alice</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">30</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">bob</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Bob</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">25</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">alice</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="w"> </span><span class="p">{</span><span class="py">since</span><span class="p">:</span><span class="w"> </span><span class="nc">2020</span><span class="p">}]</span><span class="err">-></span><span class="p">(</span><span class="py">bob</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Key</span><span class="w"> </span><span class="py">differences</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="nc">1</span><span class="err">.</span><span class="w"> </span><span class="py">Neo4j</span><span class="w"> </span><span class="py">MERGE</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">INSERT</span><span class="w"> </span><span class="kd">...</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">CONFLICT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">2</span><span class="err">.</span><span class="w"> </span><span class="py">Neo4j</span><span class="w"> </span><span class="py">FOREACH</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">supports</span><span class="w"> </span><span class="py">standard</span><span class="w"> </span><span class="py">loops</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">3</span><span class="err">.</span><span class="w"> </span><span class="py">Neo4j</span><span class="w"> </span><span class="py">apoc</span><span class="w"> </span><span class="py">functions</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="py">Geode</span><span class="w"> </span><span class="py">built</span><span class="err">-</span><span class="py">in</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span><span class="py">functions</span><span class="w">
</span></span></span></code></pre></div>
<h5 id="step-3-import-to-geode" class="position-relative d-flex align-items-center group">
<span>Step 3: Import to Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-3-import-to-geode"
aria-haspopup="dialog"
aria-label="Share link: Step 3: Import to Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><p>Create import script for bulk loading:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># import-neo4j-data.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Start Geode server</span>
</span></span><span class="line"><span class="cl">geode serve --listen 0.0.0.0:3141 <span class="p">&</span>
</span></span><span class="line"><span class="cl"><span class="nv">GEODE_PID</span><span class="o">=</span><span class="nv">$!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Wait for server to start</span>
</span></span><span class="line"><span class="cl">sleep <span class="m">5</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Import nodes</span>
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="nv">IFS</span><span class="o">=</span><span class="s1">','</span> <span class="nb">read</span> -r id name age<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> geode query <span class="s2">"CREATE (p:Person {id: </span><span class="nv">$id</span><span class="s2">, name: '</span><span class="nv">$name</span><span class="s2">', age: </span><span class="nv">$age</span><span class="s2">})"</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span> < nodes.csv
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Import relationships</span>
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="nv">IFS</span><span class="o">=</span><span class="s1">','</span> <span class="nb">read</span> -r from_id to_id since<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> geode query <span class="s2">"
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (a:Person {id: </span><span class="nv">$from_id</span><span class="s2">}), (b:Person {id: </span><span class="nv">$to_id</span><span class="s2">})
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (a)-[:KNOWS {since: </span><span class="nv">$since</span><span class="s2">}]->(b)
</span></span></span><span class="line"><span class="cl"><span class="s2"> "</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span> < relationships.csv
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Stop server</span>
</span></span><span class="line"><span class="cl"><span class="nb">kill</span> <span class="nv">$GEODE_PID</span>
</span></span></code></pre></div>
<h5 id="step-4-verify-migration" class="position-relative d-flex align-items-center group">
<span>Step 4: Verify Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="step-4-verify-migration"
aria-haspopup="dialog"
aria-label="Share link: Step 4: Verify Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h5><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Compare</span><span class="w"> </span><span class="py">counts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node_count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">()</span><span class="err">-</span><span class="p">[</span><span class="py">r</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">r</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relationship_count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Verify</span><span class="w"> </span><span class="py">specific</span><span class="w"> </span><span class="py">patterns</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">friend_count</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">10</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="janusgraph-to-geode-migration" class="position-relative d-flex align-items-center group">
<span>JanusGraph to Geode Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="janusgraph-to-geode-migration"
aria-haspopup="dialog"
aria-label="Share link: JanusGraph to Geode Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>JanusGraph uses Gremlin; convert to GQL:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-groovy" data-lang="groovy"><span class="line"><span class="cl"><span class="c1">// JanusGraph Gremlin
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">g</span><span class="o">.</span><span class="na">addV</span><span class="o">(</span><span class="s1">'Person'</span><span class="o">).</span><span class="na">property</span><span class="o">(</span><span class="s1">'name'</span><span class="o">,</span> <span class="s1">'Alice'</span><span class="o">).</span><span class="na">property</span><span class="o">(</span><span class="s1">'age'</span><span class="o">,</span> <span class="mi">30</span><span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Geode GQL equivalent
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">CREATE</span> <span class="o">(</span><span class="nl">p:</span><span class="n">Person</span> <span class="o">{</span><span class="nl">name:</span> <span class="s1">'Alice'</span><span class="o">,</span> <span class="nl">age:</span> <span class="mi">30</span><span class="o">})</span>
</span></span></code></pre></div><p><strong>Gremlin to GQL Mapping</strong>:</p>
<table>
<thead>
<tr>
<th>Gremlin</th>
<th>GQL</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>g.addV('Person')</code></td>
<td><code>CREATE (p:Person {...})</code></td>
</tr>
<tr>
<td><code>g.V().hasLabel('Person')</code></td>
<td><code>MATCH (p:Person) RETURN p</code></td>
</tr>
<tr>
<td><code>g.V().has('name', 'Alice')</code></td>
<td><code>MATCH (p {name: 'Alice'}) RETURN p</code></td>
</tr>
<tr>
<td><code>g.V().outE('KNOWS').inV()</code></td>
<td><code>MATCH (a)-[:KNOWS]->(b) RETURN b</code></td>
</tr>
<tr>
<td><code>g.V().count()</code></td>
<td><code>MATCH (n) RETURN count(n)</code></td>
</tr>
</tbody>
</table>
<h4 id="tigergraph-to-geode-migration" class="position-relative d-flex align-items-center group">
<span>TigerGraph to Geode Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="tigergraph-to-geode-migration"
aria-haspopup="dialog"
aria-label="Share link: TigerGraph to Geode Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Export TigerGraph data using GSQL:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="c1">-- TigerGraph GSQL export
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">USE</span><span class="w"> </span><span class="n">GRAPH</span><span class="w"> </span><span class="n">MyGraph</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">CREATE</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">export_data</span><span class="p">()</span><span class="w"> </span><span class="k">FOR</span><span class="w"> </span><span class="n">GRAPH</span><span class="w"> </span><span class="n">MyGraph</span><span class="w"> </span><span class="err">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">PRINT</span><span class="w"> </span><span class="n">nodes</span><span class="w"> </span><span class="k">TO</span><span class="w"> </span><span class="s2">"/tmp/nodes.csv"</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">PRINT</span><span class="w"> </span><span class="n">edges</span><span class="w"> </span><span class="k">TO</span><span class="w"> </span><span class="s2">"/tmp/edges.csv"</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">INSTALL</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">export_data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">RUN</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">export_data</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">-- Then import to Geode using similar CSV import strategy
</span></span></span></code></pre></div>
<h3 id="backup-and-restore" class="position-relative d-flex align-items-center group">
<span>Backup and Restore</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="backup-and-restore"
aria-haspopup="dialog"
aria-label="Share link: Backup and Restore">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="s3-cloud-backup" class="position-relative d-flex align-items-center group">
<span>S3 Cloud Backup</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="s3-cloud-backup"
aria-haspopup="dialog"
aria-label="Share link: S3 Cloud Backup">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Geode supports S3-compatible cloud storage for backups:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Configure S3 credentials</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>your-access-key
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>your-secret-key
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_REGION</span><span class="o">=</span>us-east-1
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Full backup</span>
</span></span><span class="line"><span class="cl">geode backup <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --dest s3://my-bucket/geode-backups <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode full <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --compression gzip
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Backup ID: 1738012345</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Size: 2.3 GB (compressed)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Duration: 45s</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Incremental backup (delta from last full backup)</span>
</span></span><span class="line"><span class="cl">geode backup <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --dest s3://my-bucket/geode-backups <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode incremental <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --parent <span class="m">1738012345</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># List all backups</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://my-bucket/geode-backups --list
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Backup ID Type Size Timestamp</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1738012345 full 2.3 GB 2026-01-23 10:00:00</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1738013456 incremental 156 MB 2026-01-23 11:00:00</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1738014567 incremental 89 MB 2026-01-23 12:00:00</span>
</span></span></code></pre></div>
<h4 id="digital-ocean-spaces-backup" class="position-relative d-flex align-items-center group">
<span>Digital Ocean Spaces Backup</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="digital-ocean-spaces-backup"
aria-haspopup="dialog"
aria-label="Share link: Digital Ocean Spaces Backup">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Digital Ocean Spaces is S3-compatible:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Configure Digital Ocean credentials</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_ACCESS_KEY_ID</span><span class="o">=</span>your-do-spaces-key
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_SECRET_ACCESS_KEY</span><span class="o">=</span>your-do-spaces-secret
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">AWS_ENDPOINT_URL</span><span class="o">=</span>https://nyc3.digitaloceanspaces.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Backup to Digital Ocean Spaces</span>
</span></span><span class="line"><span class="cl">geode backup <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --dest s3://my-space/geode-backups <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode full <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --compression gzip
</span></span></code></pre></div>
<h4 id="point-in-time-recovery-pitr" class="position-relative d-flex align-items-center group">
<span>Point-in-Time Recovery (PITR)</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="point-in-time-recovery-pitr"
aria-haspopup="dialog"
aria-label="Share link: Point-in-Time Recovery (PITR)">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Restore database to specific point in time:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Restore to specific backup</span>
</span></span><span class="line"><span class="cl">geode restore <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --source s3://my-bucket/geode-backups <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --backup-id <span class="m">1738012345</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --target /var/lib/geode/data
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Point-in-time recovery (arbitrary timestamp)</span>
</span></span><span class="line"><span class="cl">geode restore <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --source s3://my-bucket/geode-backups <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --backup-id <span class="m">1738012345</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --target /var/lib/geode/data <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --pitr-timestamp <span class="s2">"2026-01-23 10:30:00"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Process:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 1. Restore base backup (full backup 1738012345)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Apply WAL segments up to specified timestamp</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Stop at exact recovery point</span>
</span></span></code></pre></div>
<h4 id="automated-backup-strategy" class="position-relative d-flex align-items-center group">
<span>Automated Backup Strategy</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="automated-backup-strategy"
aria-haspopup="dialog"
aria-label="Share link: Automated Backup Strategy">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Set up automated backups with cron:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># /usr/local/bin/geode-backup.sh</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Configuration</span>
</span></span><span class="line"><span class="cl"><span class="nv">BUCKET</span><span class="o">=</span><span class="s2">"s3://my-bucket/geode-backups"</span>
</span></span><span class="line"><span class="cl"><span class="nv">RETENTION_DAYS</span><span class="o">=</span><span class="m">30</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Full backup on Sunday</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="k">$(</span>date +%u<span class="k">)</span> -eq <span class="m">7</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl"> <span class="nv">BACKUP_ID</span><span class="o">=</span><span class="k">$(</span>geode backup --dest <span class="nv">$BUCKET</span> --mode full --compression gzip <span class="p">|</span> grep <span class="s2">"Backup ID"</span> <span class="p">|</span> awk <span class="s1">'{print $3}'</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="nv">$BACKUP_ID</span> > /var/lib/geode/last-full-backup
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Incremental backup on weekdays</span>
</span></span><span class="line"><span class="cl"> <span class="nv">PARENT</span><span class="o">=</span><span class="k">$(</span>cat /var/lib/geode/last-full-backup<span class="k">)</span>
</span></span><span class="line"><span class="cl"> geode backup --dest <span class="nv">$BUCKET</span> --mode incremental --parent <span class="nv">$PARENT</span> --compression gzip
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Delete backups older than retention period</span>
</span></span><span class="line"><span class="cl">geode backup --dest <span class="nv">$BUCKET</span> --prune --older-than-days <span class="nv">$RETENTION_DAYS</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add to crontab</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 0 2 * * * /usr/local/bin/geode-backup.sh >> /var/log/geode-backup.log 2>&1</span>
</span></span></code></pre></div>
<h3 id="zero-downtime-migration-strategies" class="position-relative d-flex align-items-center group">
<span>Zero-Downtime Migration Strategies</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="zero-downtime-migration-strategies"
aria-haspopup="dialog"
aria-label="Share link: Zero-Downtime Migration Strategies">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="blue-green-deployment" class="position-relative d-flex align-items-center group">
<span>Blue-Green Deployment</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="blue-green-deployment"
aria-haspopup="dialog"
aria-label="Share link: Blue-Green Deployment">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Maintain two identical environments for zero-downtime upgrades:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Setup:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># - Blue environment: production (v0.1.x)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># - Green environment: staging (v0.1.x)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 1: Replicate data to green environment</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://my-bucket/migration --mode full --source blue
</span></span><span class="line"><span class="cl">geode restore --source s3://my-bucket/migration --target green
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 2: Enable continuous replication (CDC)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Configure CDC webhook from blue to green</span>
</span></span><span class="line"><span class="cl">cat > cdc-config.yaml <span class="s"><<EOF
</span></span></span><span class="line"><span class="cl"><span class="s">webhooks:
</span></span></span><span class="line"><span class="cl"><span class="s"> - name: green-replica
</span></span></span><span class="line"><span class="cl"><span class="s"> endpoint: https://green.example.com/cdc
</span></span></span><span class="line"><span class="cl"><span class="s"> retry:
</span></span></span><span class="line"><span class="cl"><span class="s"> max_attempts: 5
</span></span></span><span class="line"><span class="cl"><span class="s"> base_delay_ms: 100
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 3: Monitor replication lag</span>
</span></span><span class="line"><span class="cl">watch <span class="s1">'geode query "MATCH (n) RETURN count(n)" --host blue'</span>
</span></span><span class="line"><span class="cl">watch <span class="s1">'geode query "MATCH (n) RETURN count(n)" --host green'</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 4: Switch traffic to green (update DNS/load balancer)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># AWS Route53 weighted routing</span>
</span></span><span class="line"><span class="cl">aws route53 change-resource-record-sets <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --hosted-zone-id Z1234567890ABC <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --change-batch file://switch-to-green.json
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 5: Monitor green environment</span>
</span></span><span class="line"><span class="cl"><span class="c1"># If issues: switch back to blue (instant rollback)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># If stable: decommission blue environment</span>
</span></span></code></pre></div>
<h4 id="read-replica-migration" class="position-relative d-flex align-items-center group">
<span>Read Replica Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="read-replica-migration"
aria-haspopup="dialog"
aria-label="Share link: Read Replica Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Use read replicas to minimize downtime:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Build new version locally (run once)</span>
</span></span><span class="line"><span class="cl">git clone https://github.com/codeprosorg/geode /tmp/geode-upgrade
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> /tmp/geode-upgrade
</span></span><span class="line"><span class="cl">make build
</span></span><span class="line"><span class="cl"><span class="nv">GEODE_BIN</span><span class="o">=</span>/tmp/geode-upgrade/zig-out/bin/geode
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 1: Create read replica</span>
</span></span><span class="line"><span class="cl">geode replica create <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --primary geode-primary.example.com:3141 <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> --replica geode-replica.example.com:3141
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 2: Upgrade replica to new version</span>
</span></span><span class="line"><span class="cl">ssh geode-replica <span class="s2">"systemctl stop geode"</span>
</span></span><span class="line"><span class="cl">scp <span class="s2">"</span><span class="nv">$GEODE_BIN</span><span class="s2">"</span> <span class="s2">"geode-replica:/usr/local/bin/geode"</span>
</span></span><span class="line"><span class="cl">ssh geode-replica <span class="s2">"systemctl start geode"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 3: Test read queries on replica</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"MATCH (n) RETURN count(n)"</span> --host geode-replica.example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 4: Promote replica to primary</span>
</span></span><span class="line"><span class="cl">geode replica promote --host geode-replica.example.com:3141
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Step 5: Upgrade old primary (now secondary)</span>
</span></span><span class="line"><span class="cl">ssh geode-primary <span class="s2">"systemctl stop geode"</span>
</span></span><span class="line"><span class="cl">scp <span class="s2">"</span><span class="nv">$GEODE_BIN</span><span class="s2">"</span> <span class="s2">"geode-primary:/usr/local/bin/geode"</span>
</span></span><span class="line"><span class="cl">ssh geode-primary <span class="s2">"systemctl start geode"</span>
</span></span></code></pre></div>
<h4 id="shadow-traffic-migration" class="position-relative d-flex align-items-center group">
<span>Shadow Traffic Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="shadow-traffic-migration"
aria-haspopup="dialog"
aria-label="Share link: Shadow Traffic Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Replicate production traffic to new version for validation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Use HAProxy to mirror traffic to both environments</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># /etc/haproxy/haproxy.cfg</span>
</span></span><span class="line"><span class="cl">frontend geode_frontend
</span></span><span class="line"><span class="cl"> <span class="nb">bind</span> *:3141
</span></span><span class="line"><span class="cl"> default_backend geode_primary
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">backend geode_primary
</span></span><span class="line"><span class="cl"> server primary geode-v17.example.com:3141 check
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Mirror traffic to new version (no client impact)</span>
</span></span><span class="line"><span class="cl"> server shadow geode-v18.example.com:3141 check backup
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Monitor shadow environment for errors</span>
</span></span><span class="line"><span class="cl">tail -f /var/log/geode-v18/error.log
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Compare query performance</span>
</span></span><span class="line"><span class="cl">diff <<span class="o">(</span>geode query <span class="s2">"EXPLAIN MATCH (n) RETURN n"</span> --host v17<span class="o">)</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span> <<span class="o">(</span>geode query <span class="s2">"EXPLAIN MATCH (n) RETURN n"</span> --host v18<span class="o">)</span>
</span></span></code></pre></div>
<h3 id="schema-evolution" class="position-relative d-flex align-items-center group">
<span>Schema Evolution</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="schema-evolution"
aria-haspopup="dialog"
aria-label="Share link: Schema Evolution">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="adding-new-properties" class="position-relative d-flex align-items-center group">
<span>Adding New Properties</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="adding-new-properties"
aria-haspopup="dialog"
aria-label="Share link: Adding New Properties">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Add properties to existing nodes without downtime:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Add</span><span class="w"> </span><span class="py">optional</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="p">(</span><span class="py">backward</span><span class="w"> </span><span class="py">compatible</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">null</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Initialize</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">null</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Backfill</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="err">'</span><span class="nd">@example</span><span class="err">.</span><span class="py">com</span><span class="err">';</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Example</span><span class="w"> </span><span class="py">backfill</span><span class="w"> </span><span class="py">logic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Add</span><span class="w"> </span><span class="py">constraint</span><span class="w"> </span><span class="py">after</span><span class="w"> </span><span class="py">backfilling</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">CONSTRAINT</span><span class="w"> </span><span class="py">person_email_unique</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">ASSERT</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">UNIQUE</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="adding-new-labels" class="position-relative d-flex align-items-center group">
<span>Adding New Labels</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="adding-new-labels"
aria-haspopup="dialog"
aria-label="Share link: Adding New Labels">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Add labels to existing nodes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Add</span><span class="w"> </span><span class="py">secondary</span><span class="w"> </span><span class="py">label</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="p">=</span><span class="w"> </span><span class="py">18</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">p</span><span class="p">:</span><span class="nc">Adult</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">new</span><span class="w"> </span><span class="py">label</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Adult</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">age</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="modifying-relationships" class="position-relative d-flex align-items-center group">
<span>Modifying Relationships</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="modifying-relationships"
aria-haspopup="dialog"
aria-label="Share link: Modifying Relationships">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Transform relationship structures safely:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Old</span><span class="w"> </span><span class="py">structure</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FRIEND</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">New</span><span class="w"> </span><span class="py">structure</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="w"> </span><span class="p">{</span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">friend</span><span class="err">'</span><span class="p">}]</span><span class="err">-></span><span class="p">(</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Migration</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="p">(</span><span class="nc">idempotent</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">old</span><span class="p">:</span><span class="nc">FRIEND</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">EXISTS</span><span class="p">((</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">new</span><span class="p">:</span><span class="nc">KNOWS</span><span class="w"> </span><span class="p">{</span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">friend</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="nc">since</span><span class="p">:</span><span class="w"> </span><span class="nc">old</span><span class="err">.</span><span class="py">since</span><span class="p">}]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Verify</span><span class="w"> </span><span class="py">migration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">new_count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FRIEND</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">old_count</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Should</span><span class="w"> </span><span class="py">match</span><span class="w"> </span><span class="py">new_count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Remove</span><span class="w"> </span><span class="py">old</span><span class="w"> </span><span class="py">relationships</span><span class="w"> </span><span class="py">after</span><span class="w"> </span><span class="py">verification</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">old</span><span class="p">:</span><span class="nc">FRIEND</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DELETE</span><span class="w"> </span><span class="py">old</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="adding-indexes" class="position-relative d-flex align-items-center group">
<span>Adding Indexes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="adding-indexes"
aria-haspopup="dialog"
aria-label="Share link: Adding Indexes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Create indexes on existing data without blocking writes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="p">(</span><span class="py">non</span><span class="err">-</span><span class="py">blocking</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">Geode</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Verify</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">usage</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="p">[</span><span class="py">email</span><span class="w"> </span><span class="py">protected</span><span class="p">]</span><span class="err">'</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Output</span><span class="w"> </span><span class="py">should</span><span class="w"> </span><span class="py">show</span><span class="w"> </span><span class="s">"Index Scan"</span><span class="w"> </span><span class="py">instead</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="s">"Sequential Scan"</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="data-validation" class="position-relative d-flex align-items-center group">
<span>Data Validation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="data-validation"
aria-haspopup="dialog"
aria-label="Share link: Data Validation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="pre-migration-validation" class="position-relative d-flex align-items-center group">
<span>Pre-Migration Validation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="pre-migration-validation"
aria-haspopup="dialog"
aria-label="Share link: Pre-Migration Validation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Validate source data before migration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">orphaned</span><span class="w"> </span><span class="py">relationships</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">r</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">b</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">r</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">orphaned_relationships</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">duplicate</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span><span class="p">(</span><span class="py">by</span><span class="w"> </span><span class="py">business</span><span class="w"> </span><span class="py">key</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">email</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">email</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">count</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">email</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">invalid</span><span class="w"> </span><span class="py">property</span><span class="w"> </span><span class="py">values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err"><</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">150</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="post-migration-validation" class="position-relative d-flex align-items-center group">
<span>Post-Migration Validation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="post-migration-validation"
aria-haspopup="dialog"
aria-label="Share link: Post-Migration Validation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Verify data integrity after migration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Compare</span><span class="w"> </span><span class="py">node</span><span class="w"> </span><span class="py">counts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">labels</span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">label</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">label</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Compare</span><span class="w"> </span><span class="py">relationship</span><span class="w"> </span><span class="py">counts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">()</span><span class="err">-</span><span class="p">[</span><span class="py">r</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="kd">type</span><span class="p">(</span><span class="nc">r</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relationship_type</span><span class="p">,</span><span class="w"> </span><span class="py">count</span><span class="p">(</span><span class="py">r</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">relationship_type</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Verify</span><span class="w"> </span><span class="py">critical</span><span class="w"> </span><span class="py">queries</span><span class="w"> </span><span class="py">return</span><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="py">results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">Alice</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">integrity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SHOW</span><span class="w"> </span><span class="py">INDEXES</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="performance-optimization-during-migration" class="position-relative d-flex align-items-center group">
<span>Performance Optimization During Migration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="performance-optimization-during-migration"
aria-haspopup="dialog"
aria-label="Share link: Performance Optimization During Migration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="bulk-loading-best-practices" class="position-relative d-flex align-items-center group">
<span>Bulk Loading Best Practices</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="bulk-loading-best-practices"
aria-haspopup="dialog"
aria-label="Share link: Bulk Loading Best Practices">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Optimize bulk data imports:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># Bulk import with batching</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">BATCH_SIZE</span><span class="o">=</span><span class="m">1000</span>
</span></span><span class="line"><span class="cl"><span class="nv">TOTAL_ROWS</span><span class="o">=</span><span class="k">$(</span>wc -l < nodes.csv<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Disable constraints temporarily for faster imports</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"ALTER DATABASE DISABLE CONSTRAINTS"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Import in batches</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="o">((</span><span class="nv">i</span><span class="o">=</span>0<span class="p">;</span> i<<span class="nv">$TOTAL_ROWS</span><span class="p">;</span> <span class="nv">i</span><span class="o">+=</span><span class="nv">$BATCH_SIZE</span><span class="o">))</span><span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">"Processing batch </span><span class="k">$((</span>i/<span class="nv">$BATCH_SIZE</span> <span class="o">+</span> <span class="m">1</span><span class="k">))</span><span class="s2">..."</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> tail -n +<span class="k">$((</span>i+1<span class="k">))</span> nodes.csv <span class="p">|</span> head -n <span class="nv">$BATCH_SIZE</span> <span class="p">|</span> <span class="k">while</span> <span class="nv">IFS</span><span class="o">=</span><span class="s1">','</span> <span class="nb">read</span> -r id name age<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">"CREATE (p:Person {id: </span><span class="nv">$id</span><span class="s2">, name: '</span><span class="nv">$name</span><span class="s2">', age: </span><span class="nv">$age</span><span class="s2">})"</span>
</span></span><span class="line"><span class="cl"> <span class="k">done</span> <span class="p">|</span> geode query --batch
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Progress reporting</span>
</span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">"Imported </span><span class="k">$((</span>i+<span class="nv">$BATCH_SIZE</span><span class="k">))</span><span class="s2"> of </span><span class="nv">$TOTAL_ROWS</span><span class="s2"> rows"</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Re-enable constraints</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"ALTER DATABASE ENABLE CONSTRAINTS"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Rebuild indexes</span>
</span></span><span class="line"><span class="cl">geode query <span class="s2">"REINDEX DATABASE"</span>
</span></span></code></pre></div>
<h4 id="transaction-batching" class="position-relative d-flex align-items-center group">
<span>Transaction Batching</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="transaction-batching"
aria-haspopup="dialog"
aria-label="Share link: Transaction Batching">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Use transactions for consistent bulk operations:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Import</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">transactions</span><span class="w"> </span><span class="p">(</span><span class="py">batch</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="py">nodes</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">p1</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">1</span><span class="p">,</span><span class="w"> </span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Alice</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">30</span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">p2</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">2</span><span class="p">,</span><span class="w"> </span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Bob</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">25</span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="kd">...</span><span class="w"> </span><span class="py">998</span><span class="w"> </span><span class="py">more</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span><span class="kd">...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">p1000</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">1000</span><span class="p">,</span><span class="w"> </span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">Charlie</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="p">:</span><span class="w"> </span><span class="nc">35</span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="parallel-import" class="position-relative d-flex align-items-center group">
<span>Parallel Import</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="parallel-import"
aria-haspopup="dialog"
aria-label="Share link: Parallel Import">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Parallelize imports for faster migration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># Parallel import using GNU parallel</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Split CSV into chunks</span>
</span></span><span class="line"><span class="cl">split -l <span class="m">10000</span> nodes.csv chunk-
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Import chunks in parallel (4 workers)</span>
</span></span><span class="line"><span class="cl">ls chunk-* <span class="p">|</span> parallel -j <span class="m">4</span> <span class="s1">'
</span></span></span><span class="line"><span class="cl"><span class="s1"> cat {} | while IFS="," read -r id name age; do
</span></span></span><span class="line"><span class="cl"><span class="s1"> geode query "CREATE (p:Person {id: $id, name: \"$name\", age: $age})"
</span></span></span><span class="line"><span class="cl"><span class="s1"> done
</span></span></span><span class="line"><span class="cl"><span class="s1">'</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Cleanup</span>
</span></span><span class="line"><span class="cl">rm chunk-*
</span></span></code></pre></div>
<h3 id="troubleshooting-common-migration-issues" class="position-relative d-flex align-items-center group">
<span>Troubleshooting Common Migration Issues</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="troubleshooting-common-migration-issues"
aria-haspopup="dialog"
aria-label="Share link: Troubleshooting Common Migration Issues">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="issue-backup-timeout" class="position-relative d-flex align-items-center group">
<span>Issue: Backup Timeout</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-backup-timeout"
aria-haspopup="dialog"
aria-label="Share link: Issue: Backup Timeout">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Backup fails with timeout error</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Increase backup timeout</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_BACKUP_TIMEOUT_MS</span><span class="o">=</span><span class="m">600000</span> <span class="c1"># 10 minutes</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use incremental backups for large datasets</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://bucket/backups --mode incremental --parent <last-full-backup-id>
</span></span></code></pre></div>
<h4 id="issue-restore-corruption" class="position-relative d-flex align-items-center group">
<span>Issue: Restore Corruption</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-restore-corruption"
aria-haspopup="dialog"
aria-label="Share link: Issue: Restore Corruption">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Restore completes but data is corrupted</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Verify backup integrity before restore</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://bucket/backups --verify --backup-id <span class="m">1738012345</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># If corrupted, try previous backup</span>
</span></span><span class="line"><span class="cl">geode backup --dest s3://bucket/backups --list
</span></span><span class="line"><span class="cl">geode restore --source s3://bucket/backups --backup-id <previous-backup-id> --target /var/lib/geode/data
</span></span></code></pre></div>
<h4 id="issue-out-of-memory-during-import" class="position-relative d-flex align-items-center group">
<span>Issue: Out of Memory During Import</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-out-of-memory-during-import"
aria-haspopup="dialog"
aria-label="Share link: Issue: Out of Memory During Import">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Server crashes with OOM during bulk import</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Increase server memory allocation</span>
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">GEODE_MAX_MEMORY</span><span class="o">=</span>16GB
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Reduce batch size</span>
</span></span><span class="line"><span class="cl"><span class="nv">BATCH_SIZE</span><span class="o">=</span><span class="m">500</span> <span class="c1"># Instead of 1000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use streaming import (process one record at a time)</span>
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="nv">IFS</span><span class="o">=</span><span class="s1">','</span> <span class="nb">read</span> -r id name age<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl"> geode query <span class="s2">"CREATE (p:Person {id: </span><span class="nv">$id</span><span class="s2">, name: '</span><span class="nv">$name</span><span class="s2">', age: </span><span class="nv">$age</span><span class="s2">})"</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span> < nodes.csv
</span></span></code></pre></div>
<h4 id="issue-index-build-timeout" class="position-relative d-flex align-items-center group">
<span>Issue: Index Build Timeout</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="issue-index-build-timeout"
aria-haspopup="dialog"
aria-label="Share link: Issue: Index Build Timeout">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Symptom</strong>: Index creation times out on large datasets</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">timeout</span><span class="w"> </span><span class="py">configuration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">person_email</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">Person</span><span class="p">(</span><span class="py">email</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="p">(</span><span class="py">build_timeout_ms</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">600000</span><span class="p">)</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">10</span><span class="w"> </span><span class="py">minutes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Monitor</span><span class="w"> </span><span class="py">index</span><span class="w"> </span><span class="py">build</span><span class="w"> </span><span class="py">progress</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SHOW</span><span class="w"> </span><span class="py">INDEX</span><span class="w"> </span><span class="py">BUILD</span><span class="w"> </span><span class="py">STATUS</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="related-documentation" class="position-relative d-flex align-items-center group">
<span>Related Documentation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="related-documentation"
aria-haspopup="dialog"
aria-label="Share link: Related Documentation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><strong><a
href="/docs/configuration/server-configuration/"
>Server Configuration</a>
</strong> - Complete configuration reference</li>
<li><strong><a
href="/docs/guides/troubleshooting/"
>Troubleshooting Guide</a>
</strong> - Common issues and solutions</li>
<li><strong><a
href="/docs/query/performance-tuning/"
>Performance Tuning</a>
</strong> - Optimize query performance</li>
<li><strong><a
href="/docs/guides/schema-design/"
>Schema Design Guide</a>
</strong> - Best practices for schema modeling</li>
</ul>
<h3 id="summary" class="position-relative d-flex align-items-center group">
<span>Summary</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="summary"
aria-haspopup="dialog"
aria-label="Share link: Summary">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Geode provides comprehensive migration capabilities:</p>
<ul>
<li><strong>Version Upgrades</strong>: In-place and rolling upgrade procedures with backward compatibility</li>
<li><strong>Database Migrations</strong>: Convert from Neo4j, JanusGraph, TigerGraph to Geode GQL</li>
<li><strong>Backup & Restore</strong>: S3-compatible cloud backup with point-in-time recovery</li>
<li><strong>Zero-Downtime Strategies</strong>: Blue-green deployment, read replica migration, shadow traffic</li>
<li><strong>Schema Evolution</strong>: Safe schema modifications without downtime</li>
<li><strong>Bulk Loading</strong>: Optimized import strategies for large datasets</li>
</ul>
<p>Always test migrations in staging environments before production deployment. Use incremental backups for efficiency and verify data integrity after migration.</p>
Migration Guide
Complete guide for migrating data to Geode, upgrading between versions, migrating from other graph databases, backup and restore procedures, and zero-downtime migration strategies.