FlashDB in Go: in-memory key-value store with optional persistence

FlashDB golang tutorial: an in memory database golang option and golang key value store with Redis-style types. Covers go in memory database setup, transactions, string SET/GET/DELETE, disk vs pure memory, and links for a memory db tutorial alongside golang in memory db patterns.

Published

Updated

Read time 4 min read

Reviewed byDeepak Prasad

FlashDB in Go: in-memory key-value store with optional persistence

FlashDB is a small embedded golang key value store. If you are comparing golang in memory database options, it offers Redis-style string, hash, set, and sorted-set style operations as composable Go packages, with an optional append-only log for durability. Search queries such as in memory database golang, golang in memory db, go in memory database, or golang in-memory database often mean either pure RAM for the lifetime of the process or memory-first with disk backup—FlashDB supports both by toggling Config.Path. This memory db tutorial walks through install, opening a DB, and string SET, GET, and DELETE inside transactions.

Tested with Go 1.24 on Linux against github.com/arriqaaq/flashdb v0.1.6.


FlashDB architecture (in-memory core, optional log)

FlashDB combines in-memory structures with supporting libraries:

  • Set — unordered string collections and set algebra.
  • ZSet — sorted sets with scores (skiplist-backed).
  • ART string index — radix-tree style storage for string keys.
  • Hash — field/value maps similar to Redis hashes.
  • Append-only log (aol) — immutable log used when persistence is enabled.

For diagrams and deeper internals, see the FlashDB repository.


Install FlashDB (go get)

From a new module:

text
go mod init example.com/flashdemo
go get github.com/arriqaaq/flashdb@v0.1.6

Typical resolver output (trimmed):

text
go: added github.com/arriqaaq/aol v0.1.2
go: added github.com/arriqaaq/art v0.1.1
go: added github.com/arriqaaq/flashdb v0.1.6
go: added github.com/arriqaaq/hash v0.1.2
go: added github.com/arriqaaq/set v0.1.2
go: added github.com/arriqaaq/zset v0.1.2

Create and open a database

The main handle is *flashdb.FlashDB. Call flashdb.New with a flashdb.Config:

  • Path — directory for append-only logs. Use "" for a pure in-memory database (no files, no replay after exit).
  • EvictionInterval — interval in seconds between TTL sweeps for expired keys (set 0 to disable background eviction workers).
  • NoSync — when Path is set, NoSync: true skips fsync after writes for speed at the cost of durability if the host crashes.
go
package main

import (
	"log"

	"github.com/arriqaaq/flashdb"
)

func main() {
	config := &flashdb.Config{
		Path:             "/tmp/flashdb-demo",
		EvictionInterval: 10,
	}
	db, err := flashdb.New(config)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
}

For a RAM-only golang in memory db during development, point Path at "" (and still set EvictionInterval if you rely on TTL expiry):

go
config := &flashdb.Config{Path: "", EvictionInterval: 10}
db, err := flashdb.New(config)

Transactions: Update for writes, View for reads

All data access goes through transactions: db.Update for read-write work (only one writer at a time) and db.View for read-only snapshots. When your callback returns nil, a write transaction commits; a non-nil error rolls back changes from that transaction.


String key-value example: set, get, delete

This golang key value database example stores a small map of students, reads one email, deletes Anna, then reads again. Save as main.go beside a go.mod that already requires FlashDB.

Important detail when looping: call tx.Set for every key—return only when an error occurs, not inside the loop on the first key.

go
package main

import (
	"errors"
	"fmt"
	"log"

	"github.com/arriqaaq/flashdb"
)

func main() {
	config := &flashdb.Config{Path: "", EvictionInterval: 10}
	db, err := flashdb.New(config)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	studentMap := map[string]string{
		"Anna":   "anna@gmail.com",
		"Bob":    "bob@gmail.com",
		"Cloe":   "cloe@gmail.com",
		"Daniel": "daniel@gmail.com",
	}

	err = db.Update(func(tx *flashdb.Tx) error {
		for key, value := range studentMap {
			if err := tx.Set(key, value); err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	err = db.View(func(tx *flashdb.Tx) error {
		val, err := tx.Get("Anna")
		if err != nil {
			return err
		}
		fmt.Printf("value is %s\n", val)
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	err = db.Update(func(tx *flashdb.Tx) error {
		return tx.Delete("Anna")
	})
	if err != nil {
		log.Fatal(err)
	}

	err = db.View(func(tx *flashdb.Tx) error {
		_, err := tx.Get("Anna")
		if err != nil {
			if errors.Is(err, flashdb.ErrInvalidKey) {
				fmt.Println("Anna: key missing after delete")
			} else {
				return err
			}
		}
		val2, err := tx.Get("Bob")
		if err != nil {
			return err
		}
		fmt.Printf("Bob: %s\n", val2)
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
}

Example output from go run .:

text
value is anna@gmail.com
Anna: key missing after delete
Bob: bob@gmail.com

Summary

FlashDB gives you a go in memory database style API with optional append-only persistence when Path is non-empty—useful when you want golang in memory database speed plus restart durability. Work always happens inside Update or View transactions; string operations such as Set, Get, and Delete map cleanly to a golang key value workflow. Separate EvictionInterval (TTL sweeps) from NoSync (fsync trade-off). For another embedded in memory database golang option, see the memdb article.

String commands include SET, GET, DELETE, EXPIRE, TTL, and related helpers; hash, set, and sorted-set commands follow the Redis-like naming used in the upstream libraries—consult the FlashDB README for the full matrix.


References


Frequently Asked Questions

1. What is FlashDB?

FlashDB is an embedded key-value store written in Go that keeps primary data in memory and can optionally persist changes through an append-only log when you set a non-empty data directory.

2. Is FlashDB a golang in memory database?

Yes in the sense that working sets live in memory for fast reads and writes; when Config.Path is set it also replays and appends to on-disk log files for durability across restarts.

3. How is FlashDB different from Redis?

Redis is a separate server process and protocol; FlashDB is a Go library you link into your application with Update and View transactions rather than a network client.

4. How do I install FlashDB?

Create a module with go mod init, then run go get github.com/arriqaaq/flashdb (see the install section for a minimal go.mod example).

5. What does an empty `Config.Path` mean?

An empty path disables persistence so the database is memory-only for that process lifetime; non-empty paths enable append-only logging under that directory.

6. Why must writes use `db.Update`?

FlashDB allows many concurrent read transactions but serializes writes; Update runs your function inside a single read-write transaction that commits or rolls back as a unit.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise …