diff --git a/.gitignore b/.gitignore
index a930ab6eab7ec337c6e3a4848fa7b42a788f411a..d9498b7c9e7a691536da937bacf823a9bdaf5309 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,9 @@
 *.dylib
 /backend
 
+# database
+/db
+
 # Test binary, built with `go test -c`
 *.test
 
diff --git a/app.go b/app.go
new file mode 100644
index 0000000000000000000000000000000000000000..df0e0bc00b02fef6b8e5ef1c2107a68b1cb728d3
--- /dev/null
+++ b/app.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"time"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/fiber/v2/middleware/cors"
+	"github.com/gofiber/fiber/v2/middleware/limiter"
+	"github.com/syndtr/goleveldb/leveldb"
+)
+
+func serve(sig chan os.Signal, db *leveldb.DB) error {
+	app := fiber.New()
+
+	// cors
+	app.Use(cors.New(cors.Config{
+		AllowOrigins: conf[allowedOrigins],
+		AllowHeaders: "Origin, Content-Type, Accept",
+	}))
+
+	// rate limiting
+	app.Use(limiter.New(limiter.Config{
+		Max:        5,
+		Expiration: 7 * 24 * time.Hour, // 1 week expiration
+		LimitReached: func(c *fiber.Ctx) error {
+			log.Printf("Rate limit exceeded for IP: %s", c.IP())
+			return c.Status(fiber.StatusTooManyRequests).JSON(fiber.Map{
+				"message": "Rate limit exceeded. Max 5 registrations per week.",
+			})
+		},
+	}))
+
+	// /register
+	routeRegister(app, db)
+
+	// Graceful shutdown
+	app.Use(func(c *fiber.Ctx) error {
+		return c.Next()
+	})
+
+	// graceful shutdown
+	go func() {
+		<-sig
+		log.Println("shutting down")
+		if err := app.Shutdown(); err != nil {
+			fmt.Printf("cannot shutdown: %v", err)
+		}
+	}()
+
+	return app.Listen(conf[listenAddr])
+}
diff --git a/conf.go b/conf.go
new file mode 100644
index 0000000000000000000000000000000000000000..cb9cafb6c9df22993b66ac9dfe2e536b8e8346cd
--- /dev/null
+++ b/conf.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+	"log"
+	"os"
+)
+
+const (
+	dbPath uint8 = iota
+	listenAddr
+	allowedOrigins
+	verboseLogging
+
+	confLen
+)
+
+// env variable, default pairing
+var confEnv = [confLen][2]string{
+	{"DB", "db"},
+	{"LISTEN_ADDR", "127.0.0.1:3000"},
+	{"ALLOWED_ORIGINS", "https://hizla.io"},
+	{"VERBOSE", "1"},
+}
+
+// resolved config values
+var conf [confLen]string
+
+var verbose bool
+
+func init() {
+	for i := 0; i < int(confLen); i++ {
+		if v, ok := os.LookupEnv(confEnv[i][0]); !ok {
+			conf[i] = confEnv[i][1]
+		} else {
+			conf[i] = v
+		}
+	}
+
+	switch conf[verboseLogging] {
+	case "0":
+		verbose = false
+	case "1":
+		verbose = true
+	default:
+		log.Printf("invalid verbose value %q", conf[verboseLogging])
+	}
+}
diff --git a/db.go b/db.go
deleted file mode 100644
index 527af3ffa86668ee686985d66b4eaba4efe5ead5..0000000000000000000000000000000000000000
--- a/db.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package main
-
-import (
-	"github.com/syndtr/goleveldb/leveldb"
-	"log"
-)
-
-var db *leveldb.DB
-
-func InitDB(path string) error {
-	var err error
-	db, err = leveldb.OpenFile(path, nil)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func CloseDB() {
-	if err := db.Close(); err != nil {
-		log.Printf("Warning: Failed to close LevelDB: %v", err)
-	}
-}
-
-func SaveEmail(email string) error {
-	if err := db.Put([]byte(email), []byte("registered"), nil); err != nil {
-		log.Printf("Error saving email to LevelDB: %v", err)
-		return err
-	}
-	return nil
-}
-
-func IsEmailRegistered(email string) (bool, error) {
-	_, err := db.Get([]byte(email), nil)
-	if err != nil {
-		if err == leveldb.ErrNotFound {
-			return false, nil
-		}
-		log.Printf("Error checking email registration: %v", err)
-		return false, err
-	}
-	return true, nil
-}
diff --git a/go.mod b/go.mod
index f0ac863a8630d833b7755f90401238afb5e730da..9236dc386fbdb1360fdb2bdd28b0ef6fcbc7c196 100644
--- a/go.mod
+++ b/go.mod
@@ -1,4 +1,4 @@
-module git.randomchars.ne/hizla/waitlist/backend
+module git.randomchars.net/hizla/waitlist/backend
 
 go 1.22.3
 
diff --git a/main.go b/main.go
index e65f449f1c6a0f2d30edfeb080d0c756b14227f8..1f4cd6efd3d603ed5f3077b6c0b29fdbfd679bd4 100644
--- a/main.go
+++ b/main.go
@@ -1,104 +1,34 @@
 package main
 
 import (
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/fiber/v2/middleware/cors"
-	"github.com/gofiber/fiber/v2/middleware/limiter"
 	"log"
 	"os"
-	"regexp"
-	"time"
-)
+	"os/signal"
+	"syscall"
 
-var emailRegex = regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
+	"github.com/syndtr/goleveldb/leveldb"
+)
 
 func main() {
+	var db *leveldb.DB
 
-	app := fiber.New()
-
-	app.Use(cors.New(cors.Config{
-		AllowOrigins: os.Getenv("ALLOWED_ORIGINS"),
-		AllowHeaders: "Origin, Content-Type, Accept",
-	}))
-
-	if err := InitDB("waitlistdb"); err != nil {
-		log.Fatalf("Failed to initialize LevelDB: %v", err)
+	if d, err := leveldb.OpenFile(conf[dbPath], nil); err != nil {
+		log.Fatalf("cannot open database %q: %v", conf[dbPath], err)
+	} else {
+		db = d
 	}
-
-	defer CloseDB()
-
-	app.Use(limiter.New(limiter.Config{
-		Max:        5,
-		Expiration: 7 * 24 * time.Hour, // 1 week expiration
-		LimitReached: func(c *fiber.Ctx) error {
-			log.Printf("Rate limit exceeded for IP: %s", c.IP())
-			return c.Status(fiber.StatusTooManyRequests).JSON(fiber.Map{
-				"message": "Rate limit exceeded. Max 5 registrations per week.",
-			})
-		},
-	}))
-
-	// Waitlist registration route
-	app.Post("/register", func(c *fiber.Ctx) error {
-		type Request struct {
-			Email string `json:"email"`
-		}
-		req := new(Request)
-
-		if err := c.BodyParser(req); err != nil {
-			log.Printf("Invalid request body: %v", err)
-			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
-				"message": "Invalid request",
-			})
+	defer func() {
+		if err := db.Close(); err != nil {
+			log.Printf("cannot close database %q: %v", conf[dbPath], err)
 		}
+	}()
 
-		// Validate email format
-		if !emailRegex.MatchString(req.Email) {
-			log.Printf("Invalid email format: %s", req.Email)
-			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
-				"message": "Invalid email format",
-			})
-		}
-
-		// Check if email is already registered
-		registered, err := IsEmailRegistered(req.Email)
-		if err != nil {
-			log.Printf("Error checking email registration: %v", err)
-			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
-				"message": "Error checking registration status",
-			})
-		}
-		if registered {
-			log.Printf("Email already registered: %s", req.Email)
-			return c.Status(fiber.StatusConflict).JSON(fiber.Map{
-				"message": "Email already registered",
-			})
-		}
-
-		// Save the email to the waitlist
-		if err := SaveEmail(req.Email); err != nil {
-			log.Printf("Error registering email: %v", err)
-			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
-				"message": "Error registering email",
-			})
-		}
-
-		log.Printf("Email registered successfully: %s", req.Email)
-		return c.JSON(fiber.Map{
-			"message": "Email registered successfully",
-		})
-	})
-
-
-	// Graceful shutdown
-	app.Use(func(c *fiber.Ctx) error {
-		return c.Next()
-	})
+	sig := make(chan os.Signal, 1)
+	signal.Notify(sig, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP)
 
-	port := os.Getenv("PORT")
-	if port == "" {
-		port = "3000"
+	if err := serve(sig, db); err != nil {
+		log.Printf("cannot serve: %v", err)
 	}
 
-	log.Fatal(app.Listen(":" + port))
+	log.Println("application exit")
 }
diff --git a/register.go b/register.go
new file mode 100644
index 0000000000000000000000000000000000000000..38f846b80933dfd4718dca090482aa3b821d24c0
--- /dev/null
+++ b/register.go
@@ -0,0 +1,69 @@
+package main
+
+import (
+	"log"
+	"regexp"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/syndtr/goleveldb/leveldb"
+)
+
+var emailRegexp = regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
+
+type registration struct {
+	Email string `json:"email"`
+}
+
+// Waitlist registration route
+func routeRegister(app *fiber.App, db *leveldb.DB) {
+	app.Post("/register", func(c *fiber.Ctx) error {
+		req := new(registration)
+
+		if err := c.BodyParser(req); err != nil {
+			if verbose {
+				log.Printf("invalid request from %q: %v", c.IP(), err)
+			}
+			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
+				"message": "Invalid request",
+			})
+		}
+
+		// Validate email format
+		if !emailRegexp.MatchString(req.Email) {
+			if verbose {
+				log.Printf("invalid email from %q: %s", c.IP(), req.Email)
+			}
+			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
+				"message": "Invalid email format",
+			})
+		}
+
+		// Check if email is already registered
+		if ok, err := db.Has([]byte(req.Email), nil); err != nil {
+			log.Printf("cannot check for existence of email %q: %v", req.Email, err)
+			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+				"message": "Error checking registration status",
+			})
+		} else if ok {
+			if verbose {
+				log.Printf("duplicate email from %q: %s", c.IP(), req.Email)
+			}
+			return c.Status(fiber.StatusConflict).JSON(fiber.Map{
+				"message": "Email already registered",
+			})
+		}
+
+		// Save the email to the waitlist
+		if err := db.Put([]byte(req.Email), []byte{'x'}, nil); err != nil {
+			log.Printf("cannot register email %q: %v", req.Email, err)
+			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
+				"message": "Error registering email",
+			})
+		}
+
+		log.Printf("registered email %q", req.Email)
+		return c.JSON(fiber.Map{
+			"message": "Email registered successfully",
+		})
+	})
+}