Skip to content
S
meta

What I Learned Growing an Engineering Blog from 0 to 463,000 Pageviews

meta10 min read

I published the first posts on this blog in December 2019.

There was no launch campaign, existing audience, or reliable stream of visitors waiting for them. Like most new personal sites, the blog started at zero. I wrote about problems I had encountered, shared the posts where I could, and hoped somebody searching for the same answers would eventually find them.

By 1 August 2026, the blog had accumulated 463,362 recorded pageviews.

Along the way, it has reached readers in at least 184 countries and territories. Here’s the last month’s stats:

World map showing readers reaching the blog from countries and territories around the world

Earlier geography data is not included, so the lifetime reach may be broader.

That number is personally meaningful, but it is not the most interesting part of the story. The useful part is what happened underneath it: a small collection of practical engineering articles generated most of the traffic, some posts kept helping people for years, and many things I assumed would matter barely moved the numbers at all.

This is what I learned.

From zero to 463,362 pageviews

I calculated the lifetime total using two consecutive analytics exports with no overlapping dates.

Timeline showing the blog launching with zero visitors in December 2019, reaching 307,476 pageviews in its first three and a half years, then adding 155,886 views over the next three years for a total of 463,362 recorded pageviews

A few posts did most of the work

The distribution of traffic surprised me more than the total. Just five articles account for roughly 46% of all the pageviews the blog has recorded since launch.

The leading articles are remarkably consistent in what they offer:

ArticleLifetime pageviews
Simple In-Memory Caching in .NET with IMemoryCache86,975
Understanding WebSockets with ASP.NET43,272
Distributed Caching in ASP.NET Core with Redis31,911
Having Fun with Microsoft IoC Container for .NET Core27,812
Understanding the .NET Generic Host Model23,040

Other durable performers cover securing the Hangfire dashboard, Kubernetes commands and arguments, and gRPC across Go and .NET.

These are not broad opinion pieces. Each one helps a developer understand a specific concept or complete a specific task.

The lesson is not simply that these technologies are popular. It is that clear intent compounds. A post answering a concrete question can remain useful every day for years, even when I am not actively promoting it.

Evergreen technical writing compounds slowly

My highest-traffic article is an introduction to in-memory caching that I published in January 2020. Years later, it is still the largest entry point to the site.

That changed how I think about the return on writing.

A social post has a short distribution window. It may reach many people immediately and then disappear. A useful technical article behaves differently. It may receive very little attention on its first day, but it can be discovered repeatedly through search, links, code repositories, and recommendations.

The early results can feel underwhelming because the compounding is almost invisible. The article needs to be indexed. It needs to answer the query well enough for people to stay. Other pages need to link to it. Search engines need time to understand whether it is useful.

None of my successful posts felt like a breakthrough when I pressed publish. Their value accumulated quietly.

The blog kept working while life took priority

The growth was not driven by a perfectly consistent publishing schedule.

In 2023, I became a first-time dad. My family also moved into a new home, and I changed jobs. I wrote about that season in my plans for sahansera.dev in 2024, acknowledging that blogging had taken a back seat while I focused on being the best dad I could be.

The publication dates tell the story plainly. I published two posts in 2023, none in 2024, and returned with seven posts in 2025. I had hoped to resume a regular schedule sooner, but life had a different rhythm.

I am glad I did not treat the pause as a reason to abandon the blog. While I was not publishing, the existing articles continued answering questions, appearing in search results, and bringing new readers to the site. The work I had already done kept compounding when I did not have the time or energy to add more.

That makes the lifetime total more meaningful to me. It did not come from operating a content machine or forcing myself to publish through every season of life. It came from building a useful body of work, letting it breathe, and returning when I had something worthwhile to share.

When I started writing again in 2025, I explored streaming APIs, HTTP internals, Python environments, and home-lab Kubernetes. The break had not erased the audience. It gave me a chance to return with different experiences and better questions.

Practical specificity beats broad ambition

The best-performing titles make a small promise:

  • Configure in-memory caching.
  • Build a gRPC server or client.
  • Run Kafka locally for testing.
  • Secure a Hangfire dashboard.
  • Understand how WebSockets work.

The posts are narrow enough for the reader to know why they should click, but substantial enough to teach the surrounding concepts.

This balance matters. A title such as “Everything You Need to Know About Distributed Systems” sounds ambitious but does not reveal which problem it solves. “Building a gRPC Server in Go” is less grand and much more useful to the person who needs exactly that.

My better articles tend to combine three layers:

  1. A direct answer to a practical problem.
  2. An explanation of what is happening underneath.
  3. A working implementation readers can adapt.

That combination has become the clearest description of what I want this blog to be.

One successful article should become a cluster

For a long time, I treated each post as an isolated piece of work. The analytics show why that leaves value on the table.

The audience for an in-memory caching tutorial is likely to care about distributed caching, Redis, invalidation, cache stampedes, testing, and production failure modes. Someone building a gRPC server may next need a client, authentication, retries, deadlines, streaming, observability, or Kubernetes deployment guidance.

The gRPC series already demonstrates this. Its introduction, Go server and client, .NET server and client, and deployment posts reinforce one another. The individual posts can satisfy focused searches while the series gives interested readers a natural route through the broader subject.

I want to apply the same model to three areas:

  • .NET caching and application reliability
  • Kafka and event-driven system failure modes
  • Kubernetes operations and production troubleshooting

This does not mean publishing minor variations of the same article. Each post still needs a distinct problem and search intent. The connection between them should help a reader progress from a basic implementation to the difficult production questions.

Traffic is not the same as an audience

The historical reports showed that most visitors left after reading a single page. That sounds alarming until the context is considered.

Many visitors arrive from search, find a code sample or explanation, solve their immediate problem, and leave. For a reference-style engineering article, that can be a successful visit rather than a rejection.

At the same time, the data exposes a real weakness: I made it easy to consume one answer but did not always make the next useful step obvious.

Chronological previous-and-next links are not enough. A reader on a caching article probably does not want the post I happened to publish immediately afterward. They want the most relevant continuation of the problem they are already solving.

The improvements I am making are straightforward:

  • Add contextual links to related articles within the explanation.
  • Show a clear next step at the end of high-traffic posts.
  • Organise related material into visible series and topic hubs.
  • Keep the email and RSS subscription options easy to find.
  • Link runnable examples to maintained repositories.

The goal is not to trap somebody on the site. It is to make the site more useful when they want to go deeper.

I measured traffic but not outcomes

Another uncomfortable lesson is that I collected a lot of traffic data without defining what success should mean beyond pageviews.

My current analytics setup contains no configured conversion events. I can see that people read an article, but I cannot reliably answer questions such as:

  • Did the article lead someone to another useful post?
  • Did they subscribe by email or RSS?
  • Did they visit the example repository?
  • Did they copy a code sample?
  • Which landing pages create returning readers?

These questions matter more now than the raw total.

Pageviews helped me understand which subjects have demand. The next stage is to measure whether the blog creates a relationship with the reader. I plan to treat a confirmed email subscription as the primary conversion, then track supporting actions such as RSS clicks, repository visits, code copying, deep scrolling, and movement between related articles.

Not every personal blog needs a conversion funnel. But if I want to improve something, I need to be explicit about what “better” means.

Analytics data needs maintenance too

Just over 35% of the views in the recent export have the page title (not set). The file also contains fragmented title variants and at least one suspicious spam-like title.

That is a useful reminder that analytics is not automatically a source of truth just because it contains precise-looking numbers.

Collection can break. Titles can change. A migration can alter definitions. Filters can create misleading exports. Bots and spam can contaminate reports. Privacy settings can change how users and sessions are identified.

I will use page paths as the canonical dimension for content reporting, investigate why page titles are missing, filter known noise, and verify that a single page view is recorded for each navigation. I also want Google Search Console beside Analytics so I can see queries, impressions, rankings, and click-through rates - not only the visits that already happened.

Measurement is part of maintaining the site, not something completed by pasting in a tracking ID once.

New posts need a fair evaluation window

Several of my newer articles have far fewer lifetime views than posts published in 2020 or 2021. That does not necessarily mean they failed.

An article published last month should not be compared directly with one that has accumulated search traffic for six years. Lifetime totals reward age.

For new work, I am moving toward a smaller set of time-normalised measures:

  • Search impressions and clicks during the first 28 and 90 days
  • Views per 30 days since publication
  • Engagement and code-copy actions
  • Movement to another related article
  • Email or RSS subscription actions
  • Whether traffic continues growing after the initial promotion window

This should make it easier to distinguish a promising article that needs time from one whose topic, title, or distribution genuinely missed the mark.

What 463,000 pageviews means to me

Four hundred and sixty-three thousand is not a huge number on the scale of the internet. It is huge compared with the zero visitors I had in December 2019.

More importantly, it represents individual moments when somebody had a problem and something I wrote may have helped them move forward.

The experience has changed my view of successful technical writing:

  • You do not need a large initial audience.
  • Useful, specific posts can compound for years.
  • A handful of durable articles may matter more than a constant publishing schedule.
  • Updating and connecting existing work can be more valuable than always starting from zero.
  • Honest measurement is more useful than the largest possible headline.

If you are starting an engineering blog with no visitors, that is normal. Write down the problem you just solved. Explain enough of the underlying system that the solution remains useful. Include the details you wish had been available when you were searching.

Then publish it and give it time.

That is more or less how this blog went from zero to 463,000 pageviews - one specific problem at a time.

Stay in the loop

Practical engineering notes, without the inbox noise.

Notes on distributed systems, resilient software, and engineering in the real world - usually once or twice a month.

Unsubscribe anytime. Prefer a feed? Subscribe via RSS.