Choosing the Right Datastore for K3s: SQLite, etcd, or External SQL
Guide to choosing between SQLite, etcd, and external SQL for K3s. Compare quorum requirements, failure domains, and implementation steps for high-availability state management.
26 Aug 2025, 16:44 UTC

The State Management Dilemma in K3s
When deploying K3s, the most critical architectural decision is selecting the datastore. This component holds the entire state of your cluster—including pod definitions, secrets, and configuration—and determines whether your control plane is a single point of failure or a resilient, high-availability (HA) system.
The wrong choice leads to either unnecessary operational overhead (managing a complex database for a simple edge site) or catastrophic data loss (using a single-node store for production workloads). The primary takeaway is that SQLite is for simplicity, etcd is for self-contained HA, and External SQL is for managed reliability.
Comparing Datastore Options
K3s supports three primary modes of state management. The following table compares them based on operational constraints and failure domains.
| Feature | Embedded SQLite | Embedded etcd | External SQL (MySQL/Postgres) |
|---|---|---|---|
| Availability | Single Node | High Availability (HA) | External HA |
| Complexity | Very Low | Medium | Medium to High |
| Quorum Req. | None | Odd number of nodes | Managed by DB |
| Backup Method | File snapshot | etcd snapshot | DB Dump/Cloud Backup |
| Best Use Case | Edge/Dev/Single-node | Air-gapped HA clusters | Cloud-managed state |
Analyzing the Trade-offs
Embedded SQLite
SQLite is the default. It stores the cluster state in a local file. Because it lacks network distribution, it cannot be shared across multiple server nodes. If the node hosting the SQLite file fails, the entire cluster control plane is offline until the node is recovered.
Embedded etcd
etcd is the standard Kubernetes datastore. In K3s, you can run it in "embedded" mode, where the etcd cluster is distributed across your K3s server nodes. This removes the need for an external database but introduces the quorum requirement: you must run an odd number of server nodes (3, 5, etc.) to prevent "split-brain" scenarios, where two parts of the cluster think they are the leader.
External SQL
By connecting K3s to an external database (like PostgreSQL or MySQL), you offload the hardest part of HA—state consistency—to a dedicated system. This is ideal for teams using managed cloud databases (e.g., AWS RDS). However, it introduces network latency; if the connection between the K3s API server and the database slows down, pod scheduling and API responses will lag.
Implementation: Configuring an External SQL Datastore
To move away from the default SQLite and use an external database, you must provide the connection string during the server installation. This example assumes a PostgreSQL instance is already running and accessible.
Installation Command
Run the following command on the first server node as a user with sudo privileges. Replace the placeholders with your actual database credentials.
curl -sfL https://get.k3s.io | sh -s - server
--datastore-endpoint="postgres://username:password@db-hostname:5432/k3s_db"
Operational Checks
- Permissions: Ensure the database user has full permissions to create tables and modify schemas within the specified database.
- Connectivity: The K3s server must be able to reach the DB port (default 5432 for Postgres) via TCP.
- Risk: Changing the datastore after a cluster is already initialized with SQLite is not supported via a simple flag change. You must either migrate the data manually or reinstall the cluster.
Verifying the Configuration
To confirm K3s is using the external store rather than the local SQLite file, check the server logs on the node:
sudo journalctl -u k3s | grep "database"
Look for initialization strings that reference the postgres or mysql driver. If you see references to sqlite3, the external configuration failed or was ignored.
Rollback Procedure
Because changing the datastore changes the fundamental state of the cluster, there is no "undo" command. To revert to a default SQLite installation:
- Uninstall K3s using the provided script:
/usr/local/bin/k3s-uninstall.sh. - Remove any remaining configuration files in
/etc/rancher/k3s/. - Re-run the installation script without the
--datastore-endpointflag.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.