S
Back to portfolio
Experience · Dec 2024 — Present

Bull Teknoloji.

Software Engineer

Role
Software Engineer
Period
Dec 2024 — Present
Location
Istanbul, Türkiye · Hybrid
Stack
Next.js 16 · Go · ClickHouse
image placeholder
Bull Teknoloji — NanoShield & FLARE
public/experience/shield/orders.png
Bull Teknoloji — NanoShield & FLARE

I joined Bull Teknoloji as a software engineer in December 2024 and work across two flagship platforms: NanoShield — a real-time trading risk management system built around an FPGA core — which I lead end-to-end, and FLARE — a low-latency trading & reporting platform where I rebuilt the data path from Next.js to Go after the single-threaded Node.js event loop got buried by high-frequency market feeds.

3 min read·Dec 2024 — Present·by Shada Daab·
Ch. 01FLARE · the migration story

Next.js wasn't built for a fire-hose. So I moved the data path to Go.

FLARE delivers low-latency market data, orderbooks, candlesticks and time-and-sales to trading-floor users. The initial version routed real-time data through Next.js API routes. It worked until volume hit production levels — then the single-threaded Node.js event loop got starved by the constant message firehose, blocking everything else on the server. UI requests timed out. Charts froze.

  • Diagnosed: Node's single-threaded model + JSON parse cost on high-frequency feeds = event-loop starvation.
  • Moved the entire data path to a Go server (`golang-bullflare-ui-server`) with goroutines + channels for true parallelism.
  • Each market data domain — market data, orderbook depth, candlesticks, time-and-sales, symbol messages, positions — got its own WebSocket endpoint backed by goroutines reading from ClickHouse.
  • Next.js kept what it's good at: rendering the UI and proxying user-facing requests.
  • Result: charts stay live under production load and the UI thread never blocks on data work.
image placeholder
The firehose — live ITCH message log & orderbook state
public/experience/flare/messages.png
The firehose — live ITCH message log & orderbook state
Fig 1The firehose — live ITCH message log & orderbook state
Ch. 02FLARE · the architecture

Go + ClickHouse + gRPC + a dashboard built for traders.

The Go server (`gorilla/mux`, `gorilla/websocket`, `clickhouse-go/v2`, `golang-jwt`) exposes parallel HTTP + WebSocket endpoints — `/api/marketData/*` and `/api/marketData/*/ws` — backed by ClickHouse for the time-series side. The Next.js frontend (React 19, Turbopack, Zustand, SWR, lightweight-charts + ECharts) consumes those streams and renders a drag-and-drop dashboard (`@dnd-kit`) of resizable panels (`react-resizable-panels`). User-defined filter groups are persisted server-side per user.

User-defined filter groups are persisted server-side per user.
  • Market data, orderbook depth, candlestick, time-and-sales — each one a typed WebSocket handler in Go.
  • ClickHouse for analytical queries; gRPC for downstream service calls; JWT auth in the middleware.
  • Frontend: lightweight-charts (TradingView), ECharts, drag-and-drop layouts, saved filter groups, CSV export.
image placeholder
FLARE — live time & sales
public/experience/flare/charts.png
FLARE — live time & sales
Fig 2FLARE — live time & sales
Ch. 03NanoShield · the project I lead

Real-time risk management around an FPGA core.

NanoShield is a real-time trading risk management system — a Next.js 16 frontend, a Go backend (HTTP + WebSocket + gRPC), and a PostgreSQL schema with composite types, RLS, and NOTIFY/LISTEN triggers. Writes go through an external gRPC service into Postgres; reads come back direct; real-time updates flow through Postgres triggers → Go broadcasters → a WebSocket hub → SWR cache invalidation in the frontend.

  • Six Go broadcasters — alerts, orders, positions, limits, health, activity — each one polling Postgres, hashing for change detection, and pushing through a central WebSocket hub.
  • Hybrid SWR + WebSocket pattern: SWR for initial fetch + safety-net polling, WebSocket for instant invalidation.
  • Custom JWT auth with refresh-token deduplication (shared-promise pattern) so 50 concurrent 401s only refresh once.
  • Two Postgres pools — authDB and shieldDB — so auth tokens never compete with risk-data queries for connections.
  • Entity hierarchy: Instruments → AccountGroup → Account → User, each with their own limit types as PostgreSQL composite columns.
image placeholder
NanoShield — single-order checks & dynamic price limits
public/experience/shield/limits.png
NanoShield — single-order checks & dynamic price limits
Fig 3NanoShield — single-order checks & dynamic price limits
Ch. 04Problem-solving · query performance

From around a second to ~20 ms.

Risk dashboards are only as real-time as their slowest query. Some of the hot endpoints were taking on the order of a second under production data volumes — fine in a demo, unusable on a trading floor. I profiled the slow paths, read the query plans, and fixed the shape of the problem before reaching for caching: the right indexes, the right filter order, fewer round trips, less over-fetching.

Risk dashboards are only as real-time as their slowest query.
  • Profiled with `EXPLAIN ANALYZE` against production-scale data, not dev fixtures.
  • Added composite indexes matched to the actual filter + sort patterns of the dashboards.
  • Cut over-fetching — select only the columns the view needs, paginate the rest.
  • Collapsed N+1 patterns into single queries with joins and aggregates.
  • Measured before and after on every change — the hot paths went from ~1 s to ~20 ms.
image placeholder
Query optimization — before / after
public/experience/shield/queries.png
Query optimization — before / after
Fig 4Query optimization — before / after
Ch. 05How I work here

Cross-functional, document-first.

Hardware engineers, quants, and designers all sit at the same table. The product moves fast because we write design docs first — RBAC, alerts architecture, position checks, limits page, performance notes — and code second. Most of my value here is being the person who can talk across all three teams and translate intent into a system contract.

image placeholder
Design docs — RBAC, alerts, limits, position checks
public/experience/shield/docs.png
Design docs — RBAC, alerts, limits, position checks
Fig 5Design docs — RBAC, alerts, limits, position checks
— fin —

built by one person · case study written by the same person