

<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://adhamsalama.github.io/</id>
  <title>Adham Salama</title>
  <subtitle>A passionate backend software enginner who loves Python, TypeScript and Rust.</subtitle>
  <updated>2026-05-08T21:42:10+00:00</updated>
  <author>
    <name>Adham Salama</name>
    <uri>https://adhamsalama.github.io/</uri>
  </author>
  <link rel="self" type="application/atom+xml" href="https://adhamsalama.github.io/feed.xml"/>
  <link rel="alternate" type="text/html" hreflang="en"
    href="https://adhamsalama.github.io/"/>
  <generator uri="https://jekyllrb.com/" version="4.3.2">Jekyll</generator>
  <rights> © 2026 Adham Salama </rights>
  <icon>/assets/img/favicons/favicon.ico</icon>
  <logo>/assets/img/favicons/favicon-96x96.png</logo>


  
  <entry>
    <title>Automatic CPU Profiling Based on Event Loop Latency in Node.js</title>
    <link href="https://adhamsalama.github.io/posts/nodejs-event-loop-based-profiling/" rel="alternate" type="text/html" title="Automatic CPU Profiling Based on Event Loop Latency in Node.js" />
    <published>2025-10-28T21:53:45+00:00</published>
  
    <updated>2025-10-29T22:01:17+00:00</updated>
  
    <id>https://adhamsalama.github.io/posts/nodejs-event-loop-based-profiling/</id>
    <content src="https://adhamsalama.github.io/posts/nodejs-event-loop-based-profiling/" />
    <author>
      <name>adham</name>
    </author>

  
    
    <category term="nodejs" />
    
  

  
    <summary>
      





      Node.js is a single-threaded JavaScript runtime, so any CPU-intensive code will block the event loop.
This is a big problem for production web servers.

So how could one discover the bottleneck in their web server?

Tracing

Well, you could try tracing by auto-instrumenting your code using OpenTelemetry, and if the bottleneck is in any of the auto instrumented 3rd party libraries, you will have...
    </summary>
  

  </entry>

  
  <entry>
    <title>Building an observability platform</title>
    <link href="https://adhamsalama.github.io/posts/building-observability/" rel="alternate" type="text/html" title="Building an observability platform" />
    <published>2025-06-08T00:00:00+00:00</published>
  
    <updated>2025-06-08T00:00:00+00:00</updated>
  
    <id>https://adhamsalama.github.io/posts/building-observability/</id>
    <content src="https://adhamsalama.github.io/posts/building-observability/" />
    <author>
      <name>adham</name>
    </author>

  
    
  

  
    <summary>
      





      Recently I have been working on building an obsevability platform by myself.

This started when I tried to run Sentry locally and found out that it’s a bit complex to run, as it now requires:


  Kafka
  Clickhouse
  Snuba
  PostgreSQL
  Redis


and other stuff.

This probably makes sense for their scale as they have a multi-tenant platform that handles observability for several customers, but ...
    </summary>
  

  </entry>

  
  <entry>
    <title>Getting Real-time Database updates using PostgreSQL's LISTEN and NOTIFY</title>
    <link href="https://adhamsalama.github.io/posts/postgres-notify-listen/" rel="alternate" type="text/html" title="Getting Real-time Database updates using PostgreSQL's LISTEN and NOTIFY" />
    <published>2024-02-11T00:00:00+00:00</published>
  
    <updated>2024-02-15T21:23:47+00:00</updated>
  
    <id>https://adhamsalama.github.io/posts/postgres-notify-listen/</id>
    <content src="https://adhamsalama.github.io/posts/postgres-notify-listen/" />
    <author>
      <name>adham</name>
    </author>

  
    
    <category term="databases" />
    
  

  
    <summary>
      





      I recently discovered than PostgreSQL supports alerting clients when “something” happens, kind of like a message queue, using 2 commands, NOTIFY and LISTEN.

Here’s the description of the NOTIFY command from the PostgreSQL documentation.


  The NOTIFY command sends a notification event together with an optional “payload” string to each client application that has previously executed LISTEN cha...
    </summary>
  

  </entry>

  
  <entry>
    <title>I built a Kindle Clippings App</title>
    <link href="https://adhamsalama.github.io/posts/kindle/" rel="alternate" type="text/html" title="I built a Kindle Clippings App" />
    <published>2024-01-12T00:00:00+00:00</published>
  
    <updated>2024-01-12T00:00:00+00:00</updated>
  
    <id>https://adhamsalama.github.io/posts/kindle/</id>
    <content src="https://adhamsalama.github.io/posts/kindle/" />
    <author>
      <name>adham</name>
    </author>

  
    
  

  
    <summary>
      





      I bought an Amazon Kindle last year and absolutely loved it; I read more tech books last year than I did in my life.

I sent the some of the books to my Kindle using Amazon’s Send To Kindle app, and others using my laptop with Calibre.

Send To Kindle acts like a proxy that you send the books to, then it converts the books to Amazon’s proprietary format, and saves it to your Kindle account so t...
    </summary>
  

  </entry>

  
  <entry>
    <title>Why are Kafka messages still on the topic after the retention time has expired?</title>
    <link href="https://adhamsalama.github.io/posts/kafka-zombie-messages/" rel="alternate" type="text/html" title="Why are Kafka messages still on the topic after the retention time has expired?" />
    <published>2024-01-02T00:00:00+00:00</published>
  
    <updated>2024-01-02T00:00:00+00:00</updated>
  
    <id>https://adhamsalama.github.io/posts/kafka-zombie-messages/</id>
    <content src="https://adhamsalama.github.io/posts/kafka-zombie-messages/" />
    <author>
      <name>adham</name>
    </author>

  
    
    <category term="Messaging" />
    
  

  
    <summary>
      





      Kafka doesn’t neccessarily delete messages after retention time passed.

I encountered this issue and it took me a couple of hours until I discovered the root cause, explained in the following article. https://dalelane.co.uk/blog/?p=3993

The summary is that Kafka stores messages in segments, and it only appends to a segment or deletes it, but doesn’t update or delete individual messages in it....
    </summary>
  

  </entry>

</feed>


