DEV Community

HyperNexus
HyperNexus

Posted on • Originally published at tormentnexus.site

The Go + TypeScript Monolith: Why TormentNexus Uses Two Languages for Its AI Kernel

The Go + TypeScript Monolith: Why TormentNexus Uses Two Languages for Its AI Kernel

Explore the architectural decision behind TormentNexus's choice of a Go and TypeScript monolith. Learn why Go powers the core kernel with 446 HTTP handlers and goroutines, while TypeScript manages the business logic layer.

The Unconventional Choice: A Polyglot Monolith

In an era where microservices dominate conversations, TormentNexus bet on the power of a carefully structured monolith. Our architecture is a deliberate blend: a performance-obsessed Go core coupled with a flexible TypeScript business logic layer. This isn't a random pairing; it's a targeted strategy to build a scalable, maintainable AI backend. By embracing a polyglot architecture within a single deployable unit, we leverage the unique strengths of each language where they matter most, avoiding the operational overhead of distributed systems while retaining architectural clarity.

At its heart, TormentNexus is a single binary, a monolith in deployment but modular in design. The Go portion acts as a high-performance kernel, managing raw I/O, connection pooling, and concurrency. The TypeScript layer, compiled to a module, handles the nuanced orchestration of AI model inference, request validation, and response shaping. This separation allows our team to work in the languages best suited for the task, without sacrificing the simplicity of a unified codebase.

Why Go is the Perfect Kernel: Taming Concurrency with 446 Handlers

The kernel of TormentNexus is written in Go, and for a good reason. Our system needs to handle a high volume of concurrent, I/O-bound requests—routing them, authenticating tokens, and queuing work for AI models. Go's goroutines are the perfect tool for this. We don't just use them; we've built our entire request lifecycle around them.

Our current release registers exactly 446 HTTP handlers. Each one is a lightweight function registered with our Go-based HTTP router. When a request arrives, it's immediately wrapped in a new goroutine. This goroutine owns the request's lifecycle, from parsing the initial HTTP headers to streaming the final response. This model eliminates thread contention and allows our single process to handle thousands of in-flight requests efficiently.

// A simplified view of our kernel's handler registration
func main() {
    kernel := http.NewServeMux()
    kernel.HandleFunc("/v1/chat/completions", handleChatCompletion) // Handler #1
    kernel.HandleFunc("/v1/embeddings", handleEmbeddings)           // Handler #2
    // ... 444 more specific route handlers ...
    kernel.HandleFunc("/healthz", handleHealthCheck)                 // Handler #446

    // The kernel starts its own goroutine pool for request handling
    go listenAndServeWithMetrics(kernel, ":8080")
}

This Go kernel manages connection pools to downstream services, performs low-level protocol negotiation, and exposes detailed metrics for every one of those 446 endpoints using Prometheus counters. Its job is raw performance and reliable concurrency—the foundation upon which our more complex AI logic can safely run.

TypeScript in the Monolith: Structuring the AI Business Logic

If Go is the nervous system, TypeScript is the brain. Our core AI orchestration logic—model selection, prompt templating, token counting, response validation, and billing logic—is written in TypeScript. This layer interfaces directly with the Go kernel via in-process function calls, enabled by our monolith design.

TypeScript provides the structural rigor needed for complex, data-heavy operations. Its static type system is invaluable when working with the varied payloads and model configurations inherent in AI backends. We define strict interfaces for model responses, prompt templates, and user permissions, catching a whole class of errors at compile time that would otherwise manifest as runtime failures in a dynamically typed language.

// TypeScript defines the contracts for our AI operations
interface InferenceRequest {
    modelId: string;
    promptTemplateId: string;
    parameters: { temperature: number; maxTokens: number };
    userContext: UserPermissions;
}

interface InferenceResponse {
    generatedTokens: string[];
    tokenUsage: { prompt: number; completion: number };
    billingMeta: { costInCents: number; rateTier: string };
}

// This function is called from our Go kernel via a bridge
async function executeInference(req: InferenceRequest): Promise<InferenceResponse> {
    // Complex orchestration logic happens here
    const resolvedModel = await modelSelector.resolve(req.modelId, req.userContext);
    const templatedPrompt = await promptEngine.render(req.promptTemplateId, req.parameters);
    // ... and so on
}

This modularity allows us to update AI workflows—like adding support for a new model family or changing our billing calculation—without touching the critical, concurrency-handling Go kernel. It's the key to maintaining a Go TypeScript monolith that remains agile.

In-Process Communication: The Zero-Latency Bridge

The magic of this architecture is that the Go kernel and TypeScript layer aren't separate processes; they're part of the same binary. This eliminates all network serialization overhead that would plague a microservices approach. Our TypeScript code compiles to a WASM module or runs via a Go WASM interpreter, allowing direct function calls from our Go handlers.

When a request hits the /v1/chat/completions endpoint, the Go handler parses the HTTP request, validates the API key using local cache, and then directly invokes our TypeScript executeInference function. There's no gRPC call, no HTTP request to another service—just an in-memory function call. This architecture provides the performance benefits of a compiled language for I/O and concurrency, paired with the developer experience and type safety of TypeScript for business logic.

Deployment & Observability of a Modular Monolith

Deploying a polyglot monolith is simpler than orchestrating a mesh of microservices. We build a single, self-contained container image that includes the Go binary, the compiled TypeScript modules, and our model configuration files. Our CI/CD pipeline uses a multi-stage Docker build to compile both languages and produce a lean, secure final image. A single deployment command scales our entire AI backend together.

Observability is centralized. All metrics from the Go kernel (request latency, goroutine count, connection pool stats) and the TypeScript layer (inference durations, token usage, cache hit rates) are aggregated into a single set of Prometheus endpoints. This gives us a holistic view of system health without correlating logs across multiple services.

# Our final Docker image is a single, optimized artifact
FROM golang:1.21 as builder
WORKDIR /app
COPY . .
# Build the Go kernel which embeds the TS modules
RUN go build -tags wasmtime -o /tormentnexus-server .

FROM gcr.io/distroless/static
COPY --from=builder /tormentnexus-server /
COPY --from=builder /app/configs /configs
ENTRYPOINT ["/tormentnexus-server"]

This approach drastically reduces deployment complexity and eliminates the "polyglot sprawl" of managing different runtimes across dozens of services. It's a true modular monolith.

Conclusion: A Performant, Maintainable AI Backend

Choosing a Go + TypeScript monolith was a deliberate architectural decision for TormentNexus. It allows us to write a high-concurrency, high-performance kernel in Go while leveraging TypeScript's expressive type system for complex AI orchestration. We get the raw speed of goroutines for handling 446+ endpoints and the safety of TypeScript for our core business logic, all within a single, easily deployable unit.

This polyglot architecture proves that monoliths aren't a step backward—they can be a powerful, modern approach when designed with clear boundaries. For teams building intensive AI backend systems, this model offers a compelling blend of performance, developer ergonomics, and operational simplicity.

To see our modular monolith architecture in action or learn more about our technology choices, visit TormentNexus and explore our API documentation.


Originally published at tormentnexus.site

Top comments (0)