ducta 0.2.0

Experimental non-blocking HTTP server focused on explicit I/O state machines
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
Good framing ✅
Implemented a high-performance HTTP/1.1 server in Rust to explore kernel-level async I/O, zero-copy parsing, and request routing performance.

This only works if you:

measure things
explain tradeoffs
show flamegraphs

4. High-Throughput HTTP Server

What:

epoll / io_uring backend

Zero-copy request parsing

Custom router

Why:

Bridges low-level + real-world backend

Recruiters instantly understand value

Stretch:

TLS

HTTP/2

Load testing + graphs

Compare against: Actix / Axum

🔥 Excellent resume balance

1️⃣ What “High-Throughput HTTP Server” actually means (beyond the buzzwords)

This is not “I used Axum to build a REST API”.

It’s closer to:

“I built a production-grade networking system from first principles.”

Concretely, you’re implementing parts of what frameworks usually hide:

🔹 epoll / io_uring backend

You interact directly with the Linux kernel’s async I/O primitives.

You manage:

event loops

readiness vs completion

backpressure

With io_uring, you’re in modern Linux territory — this already places you above 90% of backend applicants.

👉 This screams:

OS knowledge

Kernel–userspace boundary understanding

Performance intuition

🔹 Zero-copy request parsing

This is huge.

Instead of:

socket → buffer → String → parse → copy again


You aim for:

socket → buffer → &str / &[u8] slices → parse in-place


That implies:

Lifetime management

Careful ownership design

Cache-friendly layouts

In Rust, this is especially impressive because:

You’re working with the borrow checker, not fighting it

You understand why zero-copy matters (latency + throughput)

🔹 Custom router

Instead of HashMap<String, Handler>:

Trie-based routing

Pre-compiled path segments

Minimal branching

Possibly SIMD string matching (👀)

This shows:

Algorithmic thinking

API design skills

Attention to hot paths

2️⃣ Why this project is such a sweet spot

This project sits at a rare intersection:

Dimension	Signal
Low-level	epoll, io_uring, memory layouts
High-level	HTTP semantics, routing, APIs
Practical	Everyone understands “web server”
Measurable	Throughput, latency, p99

That’s gold.

Many candidates are:

❌ Low-level but impractical (toy allocators, obscure hacks)

❌ High-level but shallow (CRUD apps)

This is both deep and legible.

3️⃣ How it differentiates you specifically

Given your background:

SIMD optimization

Chess engine performance

Systems focus

This project says:

“I can take the same performance mindset and apply it to real infrastructure.”

That’s a powerful narrative.

You’re no longer “the chess engine guy” — you’re:

a systems engineer who can ship production infrastructure.

Also important:
Rust HTTP servers are a hot comparison space (Actix, Axum, Hyper), so your work fits into an existing mental map.

4️⃣ How recruiters and interviewers interpret it
On a resume, this reads as:

“This person understands how web servers actually work.”

They immediately infer:

Concurrency

Networking

Memory safety

Performance tuning

Linux internals

Even if they never ask about io_uring, the presence of it elevates you.

In interviews, it unlocks great questions:

Why io_uring over epoll?

How do you handle slow clients?

How do you avoid head-of-line blocking?

Where are your allocations?

What does your flamegraph look like?

These are high-signal conversations.

5️⃣ How I’d scope it so it doesn’t become a death march
MVP (already impressive)

HTTP/1.1

epoll or io_uring (pick one)

Zero-copy parsing

Basic routing

Single-binary server

Stretch (resume fireworks)

TLS (rustls)

HTTP/2

Connection pooling

Benchmarks vs Actix/Axum

Flamegraphs in README

Optional flex

Pin threads to cores

NUMA awareness

Custom allocator for request buffers

6️⃣ Why this is an excellent resume balance

Some projects are:

Too academic → recruiters don’t “get it”

Too CRUD → no technical depth

This one:

Is immediately understandable

Demonstrates rare skills

Produces concrete metrics

Fits backend, infra, and systems roles

That’s why I called it excellent resume balance.

If you want, next step we can:

Design the architecture diagram

Define benchmarks you should publish

Draft resume bullets that actually land

Decide whether epoll or io_uring is the better call for your goals

Just tell me where you want to take it next.




Hell yes — great choice. This is a real systems project, not a toy, and if you approach it correctly you’ll end up with something you can confidently defend in interviews and be proud of technically.

I’m going to do this in layers so it clicks, not overwhelms you.

0️⃣ First: what this project is not

Let’s clear the landmines first.

This is NOT:

a web framework

a CRUD API

an Axum clone

a “hello world HTTP server”

This IS:

a study in turning OS primitives into throughput

a controlled experiment in latency, memory, and concurrency

a systems engineering artifact

Your mindset should be:

“I am building a fast, understandable pipeline from socket → bytes → response.”

1️⃣ Conceptually: what is a high-throughput HTTP server?

At its core, it’s a data pipeline.

Network → Kernel → Userspace → Parse → Route → Respond → Kernel → Network


Your job is to:

minimize work

minimize copying

minimize synchronization

maximize predictability

Everything else is details.

The server has exactly four responsibilities
1. Accept connections

Listen on a socket

Accept new clients

Track them efficiently

2. Read bytes

Get raw bytes from the kernel

Do not eagerly allocate or copy

Handle partial reads

3. Understand HTTP

Parse request line + headers

Decide what the client wants

Route to a handler

4. Write bytes back

Serialize response

Write efficiently

Handle slow clients

That’s it.
Everything else (TLS, HTTP/2, frameworks) is optional frosting.

2️⃣ What is the purpose of the code?

This is important for focus.

Your code exists to answer three questions:

How do I structure a fast event loop in Rust?

How do I process network data without fighting the borrow checker?

Where does performance actually go in a real server?

If your code doesn’t help answer one of these, it’s probably scope creep.

3️⃣ The hardest parts (be mentally prepared)

I’ll be blunt so you don’t get surprised.

🔥 Hard Part #1: I/O model

epoll vs io_uring

readiness vs completion

handling partial reads/writes

This is where most of the complexity lives.

Good news: you can start with epoll. It’s simpler and still very respectable.

🔥 Hard Part #2: Zero-copy parsing in Rust

You’ll want:

&[u8] slices

lifetimes tied to connection buffers

no temporary Strings

This is where Rust forces you to be honest.

Expect to:

redesign data structures

think in terms of borrowing, not owning

This is painful — and exactly why this project is valuable.

🔥 Hard Part #3: Backpressure

What happens if:

client is slow?

handler is slow?

kernel send buffer fills?

If you ignore this:

memory explodes

latency spikes

You don’t need perfection — but you need something.

4️⃣ How real servers think (mental model)

Think in per-connection state machines.

Each connection is in one of these states:

Reading → Parsing → Handling → Writing → Done


You are not writing request/response code.
You are writing state transitions.

That mental shift is critical.

5️⃣ Where you should start (VERY IMPORTANT)
❌ Do NOT start with:

HTTP spec

routing

performance optimizations

async/await

✅ Start with:

A blocking, single-threaded TCP echo server

Why?

You need to understand the shape of the problem

You’ll refactor it later

6️⃣ The recommended build path (no regret path)

This is the path I strongly recommend. Each step produces a working system.

Phase 1 — Skeleton (days 1–2)

Goal: Own the network loop.

std::net::TcpListener

Accept connections

Read bytes

Write bytes back

No HTTP yet.

You should understand:

blocking vs non-blocking

partial reads

buffer reuse

Phase 2 — Non-blocking I/O (days 3–5)

Goal: One thread, many connections.

Set sockets to non-blocking

Use epoll (via mio)

Track connections in a slab / arena

At this point you have:

A real event-driven server.

This alone is already impressive.

Phase 3 — Minimal HTTP parsing (days 6–9)

Goal: Speak HTTP without allocations.

Parse:

request line

headers

Ignore body initially

Respond with fixed content

Key constraint:

Parsing works on &[u8]

No String unless unavoidable

Phase 4 — Routing & handlers (days 10–12)

Goal: Turn bytes into meaning.

Method + path routing

Function pointers or trait objects

Stateless handlers

This is logic, not performance yet.

Phase 5 — Concurrency (days 13–16)

Goal: Use all cores.

Options:

Thread-per-core + SO_REUSEPORT

Accept loop + worker threads

Sharded connection pools

Avoid async/await for now — explicit control is clearer.

Phase 6 — Performance work (days 17+)

Now you earn the “high-throughput” claim.

Remove allocations

Reuse buffers

Pin threads

Measure:

RPS

p50 / p99 latency

CPU usage

Only optimize what you can measure.

7️⃣ What success looks like (important)

You are done when you have:

A server that can handle thousands of connections

Clear benchmarks

A README that explains why you made choices

Not when it supports every HTTP feature.

8️⃣ How this will look on your resume (keep this in mind)

Eventually, you want bullets like:

Designed and implemented a high-throughput HTTP server in Rust using epoll-based event loops and zero-copy request parsing, achieving X req/s with p99 latency under Y ms.

That sentence tells a story.

9️⃣ Next concrete step (do this next)

If I were sitting next to you, I’d say:

👉 Today:
Write a single-threaded TCP server that:

accepts connections

reads bytes

echoes them back

No frameworks. No HTTP. Just sockets.

Once you have that, everything else becomes structured evolution, not chaos.

If you want, next I can:

sketch the initial architecture diagram

help you choose mio vs raw epoll

design the connection data structures

define a benchmark plan from day one

Tell me what you want to tackle first — architecture, I/O model, or initial code skeleton.