Skillversitas

Bokeh Server

The Bokeh server runs your Python app as a long-lived process that keeps the full data in memory and synchronizes only what changed to connected browsers. This is the scalable path: large DataFrames, user sessions, callbacks that hit a database, and multi-user dashboards. You write an app function, decorate it with document, and run it with bokeh serve.

A Simple Server App

# file: server_app.py
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.models import Button, ColumnDataSource
from bokeh.layouts import column
import random

p = figure(title="Click to add a point")
source = ColumnDataSource(data={"x": [], "y": []})
p.circle("x", "y", source=source, size=10)

def add_point():
    source.stream({"x": [random.random()], "y": [random.random()]}, max_size=1000)

btn = Button(label="Add point", width=150)
btn.on_click(add_point)

doc = curdoc()
doc.add_root(column(btn, p))
doc.title = "Bokeh Demo"
bokeh serve server_app.py
# open http://localhost:5006/server_app

The curdoc Model

  • curdoc() is the Document bound to the current connection - your per-user session.
  • add_root places a layout in the session; each browser gets its own copy of the document.
  • Modify models (source.data, glyph.y) and the change syncs to that user's browser automatically.

Periodic Callbacks (Live Data)

from bokeh.models import PeriodicCallback

def tick():
    source.stream({"x": [now()], "y": [metric()]}, max_size=60)

timer = PeriodicCallback(callback=tick, period=1000)
timer.start()
curdoc().add_next_tick_callback(timer.add_to_doc)

Multiple Users, Isolated State

Because each connection gets its own Document, two browsers on the same app have independent state by default. For shared state (a live counter everyone sees), synchronize through a shared model, a database, or an event bus outside the document.

Serving Many Apps

bokeh serve ./apps/          # every .py in apps/ becomes /<name>
bokeh serve --show sales.py  # launch and open in browser
bokeh serve --port 8080 --allow-hosts "localhost:3000" sales.py

Deploying a Bokeh Server

  • Run under a process manager (systemd, supervisor) or in a container; it is a normal Python server.
  • Put it behind a reverse proxy (nginx/Caddy) for TLS; pass the Host header through.
  • Set --allow-hosts for the proxy's origin, and use --num-processes for multiple worker processes (each with its own memory).

Summary

Bokeh server apps are Python functions using curdoc(): build your layout, add it with doc.add_root, and mutate models to sync changes to each user's browser. Add PeriodicCallback for live streams, run with bokeh serve (one app per file, multi-user by default), and deploy behind a reverse proxy with --allow-hosts configured.