RSSAmplifier

Blog

Segflow

Recent content on Segflow

segflow.github.ioRSS feed ↗19 posts

Latest posts

Finding a needle in a 4 GB haystack: from 0.75 GB/s to 49 GB/s in Go

I had a 4 GiB file that’s almost entirely zeros, exactly one non-zero int64 is hiding at offset Size - 8 (the last aligned slot). The task: find that offset, as fast as possible, in Go on Linux. It’s a deliberately silly problem. There’s no parsing, no indexing, no cleverness on the algorithm side. The only thing it measures is how much data we can pull through a CPU per second.…

No, you don't need Oh My Zsh

Don’t get me wrong – Oh My Zsh is an excellent product. It’s well-maintained, feature-rich, and has helped millions of developers enhance their shell experience. But here’s the thing: you don’t need it to have a great zsh experience . When I recently set up a new workstation, I decided to skip Oh My Zsh entirely and configure zsh manually. The result? A lightweight, fast,…

The case against helper packages named `utils`

I argued earlier that a function’s signature should never lie , and then that errors are values only if you treat them like values . Both posts circled the same question at different scales: what is this code for? This one closes the loop at the package level. The short version: if your package is named utils , you don’t have an answer.

Errors are values, but only if you treat them that way

Last time I argued that a function’s signature should never lie . The error return is the most lied-about part of every Go signature I read. It gets logged, swallowed, repackaged, panicked on, and printed back to the user as internal error: internal error: internal error . Three habits keep it honest.

Self-explained function signatures

A function I once shipped looked like this: func Process ( data [] byte ) error Innocent. You give it bytes, it returns an error. What more do you need? Plenty, as it turned out. Process also wrote a file to /tmp , posted the same bytes to a webhook, and stashed a copy in a package-level global so the next call could “diff against the last one”. None of that was in the signature. None…

Zero-copy in Go: sendfile, splice, and the cost of io.Copy

A small file-serving service of mine slowed to a crawl one afternoon after a “harmless” middleware change. CPU on the server box doubled, throughput roughly halved. The diff was a single line: instead of handing a *os.File to io.Copy , somebody had wrapped it in a tiny logging reader to count bytes. That one wrap quietly turned off sendfile(2) . This post is about that fast path: what…

Bounds-check elimination in Go: making the prover happy

I had a hot loop I could not get any faster. Plain for i := 0; i < n; i++ , two slice reads, one add, return. On paper that is three or four x86 instructions per iteration. In practice it was running at about half the throughput I expected, and perf kept pointing at the same two lines. When I finally dumped the assembly, the answer was sitting right there: a CMPQ followed by a conditional jump to…

Backpressure for the impatient: channels vs. semaphores vs. tokens

A pipeline has backpressure when the consumer can make the producer slow down, or refuse the work, or both. A bigger buffer does neither. It just defers the same problem, with more memory held hostage in the meantime. The two get confused a lot, and the difference shows up unmistakably in the tail latency numbers, so this post does the comparison directly. When load exceeds capacity you have three…

What strace -c taught me about a fast CLI

The CLI was fast. I had benchmarked it on my laptop, on a fresh clone of the repo, and it finished in well under a second. Then a coworker pointed it at a real monorepo, the kind with 30,000 files spread across a few thousand directories, and the thing crawled. Same code, same machine class, just more files. The user-visible work had not changed. The wall clock had. This is the story of the half…

Escape analysis, demystified by 6 tiny examples

A while back I had a hot loop that profiled like a heap-allocation machine gun. pprof blamed runtime.mallocgc . The code looked innocent. The fix turned out to be a one-line signature change, and the compiler had been quietly screaming at me about it the whole time via -gcflags=-m . This post is the second half of a tour I started in My journey optimizing the Go Compiler and continued in What…

Designing for deletion

A few months ago my team had to kill a feature. Nothing dramatic; a half-finished onboarding flow product had quietly stopped believing in. The ticket said &ldquo;remove the new welcome wizard.&rdquo; I estimated two days. It took three weeks. The wizard itself was about 400 lines. The reason it took three weeks is that those 400 lines had grown roots. A flag on the user record. A column in the…

Tuning a Go TCP server toward 1M idle connections on a laptop

I had been telling people for months that Go can &ldquo;trivially&rdquo; hold a million idle TCP connections. The runtime uses epoll, goroutines are cheap, what could go wrong. Then a colleague asked me to actually do it, and I realised I had never tried. So I sat down with my laptop, a fresh net.Listen , and a client that just wants to open a lot of sockets. The first wall I hit was 1024 file…

Inlining budgets, and why your one-liner stayed slow

After my map-lookup contribution to the Go compiler back in April, I kept poking the toolchain whenever a benchmark surprised me. Last week it surprised me again, and the lesson is short enough to fit in one post: Go inlines aggressively, but not infinitely, and the shape of your function matters more than its length. The story starts with a three-line helper that I was sure the compiler would…

My journey optimizing the Go Compiler

At EDGE we write a lot of Go, and we love it for various reasons, one of them being speed. One day I got into a situation where I need to assign an int to a variable based on another string value. Sounds easy right? well yes, but this particular use case awakened the beast in me and made me think what&rsquo;s the best way to do it. The journey finished by me contributing to the language compiler…

Noxale CTF: Grocery List (pwn)

In this challenge, we are given a service IP and PORT, to which we can connect using netcat or any similar tool. We are also provided with an ELF file.

PlaidCTF: Shop (pwn)

Below, you will find the full exploit for PlaidCTF pwn200 task. The full write-up will follow.

AceBear CTF: Secure login (reverse)

In this article I will share with you the solution to Secure Login challenge presented at Acebear CTF , this task was worth 900 points. Even though I did not manage to solve the challenge on time, I still enjoyed it a lot.

34C3 CTF: GiftWrapper 2 (pwn)

In this challenge, we are given a service IP and PORT, to which we can connect using netcat or any similar tool. We are also provided with a tar file that contains the service binary and some .so modules.

3DS CTF: Xesar (crypto)

Recently I decided to start playing CTFs again, and since I needed some training before playing a real one, I decided to take a look at some recent CTFs in CTFtime.org . And then I found this crypto task with no write-up for it yet, and that&rsquo;s why I jumped into it :)