> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# BYOD — Bring Your Own Database

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>BYOD connects a FastEdge Edge Storage store to an external Redis-compatible database, giving applications access to existing data without migrating it to Gcore's hosted storage. Applications access a BYOD store through the same [JavaScript SDK](https://g-core.github.io/FastEdge-sdk-js/reference/fastedge/kv/open/) or [Rust SDK](https://docs.rs/fastedge/latest/fastedge/key_value/struct.Store.html) as a regular store — no code changes required.</p>

    <p>Any store implementing the Redis protocol is supported: Redis, [Apache Kvrocks](https://kvrocks.apache.org/), and other Redis-compatible key-value stores. The external store must be publicly accessible, since Gcore's edge nodes connect to it over the network on each request.</p>

    ## Hosted Edge Storage vs BYOD

    <p>With hosted Edge Storage, data is replicated across Gcore's edge network and reads are served from the nearest edge location — latency is typically in the single-digit milliseconds. With BYOD, each read is a live query to the external database, so response time depends on the network distance between the edge location and the database host.</p>

    <p>BYOD is a practical choice for development, testing, or workloads where read latency is not critical. For latency-sensitive production workloads, hosted Edge Storage is recommended.</p>

    <p>Supported connection URL schemes:</p>

    * `redis://` — standard Redis protocol
    * `rediss://` — Redis protocol over TLS

    <p>URL format: `redis://:password@host:port/db-index` or `redis://username:password@host:port/db-index`</p>

    ## Create a BYOD store

    <p>To create a BYOD store, open the [Gcore Customer Portal](https://portal.gcore.com/accounts/reports/dashboard), navigate to **FastEdge**, and select **Edge Storage** in the sidebar.</p>

    <Steps>
      <Step title="Start the wizard">
        Click **Add Edge Storage** in the top-right corner.

        <Frame>
          <img src="https://mintcdn.com/gcore/1bA_7wZnxXhG8zar/images/docs/fastedge/kv-stores/manage-kv-store/add-store.png?fit=max&auto=format&n=1bA_7wZnxXhG8zar&q=85&s=05cf71ab71c147d0f3c461e9fe8b1a88" alt="Edge Storage list with Add Edge Storage button highlighted" width="1480" height="385" data-path="images/docs/fastedge/kv-stores/manage-kv-store/add-store.png" />
        </Frame>
      </Step>

      <Step title="Enter a name">
        Enter a name and optionally a description.
      </Step>

      <Step title="Enable BYOD">
        Select the **BYOD: Bring Your Own Database** checkbox. Two additional fields appear:

        1. **URL** — the connection URL for the Redis-compatible store. For example: `redis://:mypassword@redis.example.com:6379/0`
        2. **Prefix** — a string prepended to every key when FastEdge reads or writes the store. For example, with prefix `app:prod:`, a read for key `greeting` retrieves `app:prod:greeting` from the external database. Leave blank if no namespacing is needed.

        <Frame>
          <img src="https://mintcdn.com/gcore/1bA_7wZnxXhG8zar/images/docs/fastedge/kv-stores/manage-kv-store/byod-create-storage-form.png?fit=max&auto=format&n=1bA_7wZnxXhG8zar&q=85&s=e7fc28cf83fb2a4d00bb03d6f4bcf242" alt="Add Edge Storage form with BYOD checkbox selected, URL and Prefix fields filled in" width="1400" height="625" data-path="images/docs/fastedge/kv-stores/manage-kv-store/byod-create-storage-form.png" />
        </Frame>
      </Step>

      <Step title="Create the store">
        Click **Create Edge Storage** to validate the connection and save the store.

        <Info>
          Gcore validates the connection at creation time. If the host is unreachable, the port is blocked, or the credentials are wrong, the store is not created and an error message is displayed. Verify that the store is publicly accessible and the URL is correct, then try again.
        </Info>

        <Warning>
          A store's type cannot be changed after creation. A BYOD store cannot be converted to hosted storage.
        </Warning>
      </Step>
    </Steps>

    ## Link to an application

    <p>After creation, link the BYOD store to a FastEdge application using the same process as a regular store — instructions are in [Managing applications](/fastedge/manage-apps#edge-storage). The prefix is applied transparently and application code does not need to know whether the store is BYOD or hosted.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Create a BYOD store by passing a `byod` object to the standard store creation endpoint. Once created, a BYOD store uses the same data endpoints as a regular [Edge Storage store](/fastedge/kv-stores/manage-kv-store).</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required. Use the store ID from the creation response or from the list endpoint.
    </Info>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export STORE_ID="{YOUR_STORE_ID}"
    ```

    ## Create a BYOD store

    <p>The `byod.url` field accepts `redis://` and `rediss://` (TLS) schemes. The optional `byod.prefix` string is prepended to every key on reads and writes — use it to namespace application data within a shared Redis instance.</p>

    ```bash theme={null}
    curl -X POST "https://api.gcore.com/fastedge/v1/kv" \
      -H "Authorization: APIKey $GCORE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "my-byod-store",
        "byod": {
          "url": "redis://:mypassword@redis.example.com:6379/0",
          "prefix": "app:prod:"
        }
      }'
    ```

    <p>The API returns the store ID used in all subsequent data requests:</p>

    ```json theme={null}
    {
      "id": 131,
      "name": "my-byod-store",
      "app_count": 0,
      "size": 0
    }
    ```

    <Warning>
      A store's type cannot be changed after creation. A BYOD store cannot be converted to hosted storage.
    </Warning>

    ## Data operations

    <p>Inserting, listing, and deleting key-value pairs in a BYOD store uses the same [Edge Storage endpoints](/fastedge/kv-stores/manage-kv-store) as a hosted store — the `byod.prefix` is applied transparently on every request.</p>
  </MethodSection>
</MethodSwitch>
