Ship tools as standalone static binaries
Jul 04, 2025
Open AI is ditching TypeScript to rebuild Codex in Rust. This is a great example of why you should always ship tools as standalone static binaries using compiled languages. Reddit Comment The biggest...
Maintaining an Android app is a lot of work
Jun 07, 2025
There was recent news about 47% decline in the number of apps on Google Play Store. As a hobby Android developer, who has been developing MusicSync, a Google Play Music + Podcast replacement for the ...
FastAPI vs Flask performance comparison
May 10, 2025
If you are running Python in production, you will almost certainly have to decide which web framework to use. Let’s consider a rudimentary Hello world based test comparing the performance of two...
How to run Python in production
Apr 19, 2025
My previous article recommended that one should reconsider using Python in production. However, there’s one category of use case where Python is the dominant option for running production workl...
It is hard to recommend Python in production
Mar 08, 2025
I started writing in the 2010s when Python 2 was going to be deprecated and Python 3 was too early to support. Python might have died there and then but was picked up by the data science and machine ...
Android: Don't use stale views
Dec 23, 2024
In MusicSync, one of the views became complex and too slow to be inflated on the UI thread. So, I decided to do some Pooling around it to inflate it on the background thread and use it on the UI threa...
Repairing database on the fly for millions of users
Oct 05, 2024
This is a story of a messaging app used by billions of users. The app followed an extremely strong model of privacy. The app never persisted the user’s data on the servers. All the communication...
It is hard to recommend Google Cloud
Sep 21, 2024
Google Domains A year back, I had to migrate my domain after Google decided to shut down Google Domains. I had to, not only, painfully setup multiple side-projects subdomain mappings again on a new d...
Use Makefile for Android
May 11, 2024
I use Makefile for Android just like I use Makefile for my non-Android side-projects....
Android Navigation: Up vs Back
Apr 20, 2024
Android has two distinct navigation guidelines as opposed to iOS. Getting them right is nuanced....
Abstractions should be deep not wide
Mar 23, 2024
Let’s say you are building a git analytics product. Your product supports GitHub and GitLab for now. It might support more products in the future. 90% of the codebase that supports GitHub and Gi...
Always support compressed response in an API service
Mar 09, 2024
If you run any web service always enable support for serving compressed responses. It will save egress bandwidth costs for you. And, more importantly, for your users. Over time, the servers as well as...
Hermetic docker images with Hugging Face machine learning models
Feb 29, 2024
Hugging Face is GitHub for machine learning models. Their on-the-fly model download scheme, however, is difficult from a DevOps perspective. Here’s how to disable it. ...
API services should always have usage Limits
Feb 11, 2024
Every public-facing API service should have API usage limits. If this seems overkill then ask yourself if would it be OK if a single IP sends a million requests a second. This does not apply just to p...
Best practices for using Python & Poetry inside Docker
Jan 13, 2024
The ultimate guide to using Poetry inside Docker...
How to add a new formula to homebrew package manager
Dec 16, 2023
I recently added adb-enhanced to the Homebrew package manager. Here are some of my learnings and future tips to smoothen up the process....
How to setup Go packages under monorepo
Nov 04, 2023
Let’s say you want to have two Go packages pkg1 and pkg2 in a monorepo setup. Here’s what a good project structure would look like....
Android: Always show toasts on the background thread
Oct 21, 2023
I used to call Toast#show() on the UI thread. Then one day, I received notifications related to an ANR (Application Not Responding) error in one of my Android apps. Java 1 2 3 4 5 6 7 8 9 10 11 at and...
How to deploy Docker images on Microsoft Azure
Sep 02, 2023
There are several ways to deploy Docker images on Microsoft Azure. My favorite one is Azure App Service/Web Application for Containers. This is the closest to Google Cloud Run....
End-to-end testing of mobile apps
Aug 01, 2023
Google released a new version of the Google Auth library. It had a bug that broke Google Login on Android for API 26 and earlier. This impacted my small but popular Music Player app in Google Play. It...
API backend should use dataloaders
Jun 15, 2023
Data Loaders allow transparent batching of requests to a data provider (e.g. database). More often than not, this leads to reduced latency and better performance without forcing an explicit batching o...
Generics in Go
Apr 02, 2023
Generics in Go were added about a year back in Go 1.18. In my experience they are great and they fix one of the biggest roadblocks in terms of writing reusable code in Go. I’ll illustrate that w...
Common pitfalls of GitHub Actions
Mar 18, 2023
If you create GitHub Actions via GitHub’s UI by going to the URL of the form `https://github.com///actions/new`, it provides templates for setting up the build. However, the template is broken. ...
Inheritance in Go language
Mar 04, 2023
Go language does not have the concept of a class directly. It, however, has a concept of an interface as well as a struct. I’ll illustrate how this can be used to build most of the inheritance c...
Bad and good ways to test code
Feb 18, 2023
Writing tests at an early-stage startup is always heatedly debated. If a function has one call, adding a unit test doubles the number of calls, this not only doubles the current work but even slows do...
GraphQL vs gRPC
Feb 12, 2023
RPC calls allow one service to call functions in another service as if it is a part of the same service. And unlike a REST API, one gets strong type checking. The two services can even be in different...
Android uncaught exception handler and ANR
Sep 10, 2022
While trying to install a custom exception handler to catch uncaught exceptions (crashes), I ended up writing...
Infinite network timeouts in Java and Go
Jun 12, 2022
Java made a huge mistake of having no network timeouts. A network request can block a thread forever. Even Python did the same. The language designers should have chosen some conservative appropriate ...
Test changes to CircleCI config locally
Sep 12, 2021
Rather than pushing the code to a remote branch and then testing via Circle CI servers, it is best to run the tests locally first and make them work. Here’s how you can do that....
Android: Catching NDK crashes
Feb 06, 2021
On Android catching Java exceptions is easy via UncaughtExceptionHandler. Catching NDK crashes is a bit more convoluted. Since the native stack is probably corrupted, you want the crash handler to run...
Docker: Be careful about the scratch image
Dec 08, 2020
After I wrote my previous post, some suggested that I can cut down the image size further by using a “scratch” image. And that’s true, “scratch i"s a reserved 0-sized imag...
How many source-code repositories should a startup have
Oct 01, 2020
Recently, this question came up during the discussion. “How many source-code repositories should a startup have?” There are two extreme answers, a single monorepo for all the code or repos...
Incremental testing: save time and money on CI for monorepo
May 06, 2020
To use monorepo or not is an eternal debate. Each has its pros and cons. Let’s say you decide to go with monorepo, one major issue you will face over time is slow testing. Imagine a monorepo, co...
How to deploy side projects as web services for free
Apr 18, 2020
In 2020, the web is still the most accessible permission-less platform. For the past few months, I have been playing and building side projects to simplify my life. I started with a Calendar Bot for s...
Docker 101: A basic web-server displaying hello world
Apr 13, 2020
A basic webserver Docker containers are small OS images in themselves that one can deploy and run without worrying about dependencies or interoperability. All the dependencies are packed in the same c...
Consoles by Google
Apr 04, 2020
A single developer has to sometimes deal with 7 different consoles by the same company…...
Troubleshooting Android Emulator: Process finished with exit code 1
Mar 07, 2020
Emulator: Process finished with exit code 1 You opened AVD Manager in Android Studio and tried to start an AVD, you got “Emulator: Process finished with exit code 1”. Following are the ste...
Android: Using "Die with me" app without killing the phone's battery
Feb 08, 2020
Die with me is a chat app which can be used only when the phone’s battery is below 5%. Here is a fun way to use the app without draining your phone’s battery. Connect the phone via ADB or...
The first two statements of your BASH script should be...
Jan 11, 2020
Sh 1 2 #!/usr/bin/env bash set -euo pipefail The first statement is a Mac, GNU/Linux, and BSD portable way of finding the location of the bash interpreter. The second statement combines ...
Keep your dotfiles bug-free with Continuous Integration
Dec 01, 2019
Ultimate guide to setting up and maintaining CI of your dotfiles...
Circle CI vs Travis CI
Sep 01, 2019
Update: As of Mar 2022, I recommend everyone to use GitHub Actions I maintain a somewhat popular Android developer tool ( adb-enhanced). The tool is written in Python, supporting both Python 2 and 3. ...
Stanford CS251: Cryptocurrencies, blockchains, and smart contracts
Apr 01, 2019
Lectures Introduction Creating a Digital currency Bitcoin Overview Bitcoin Blockchain Bitcoin Mining Bitcoin Miner interactions and Game Theory Cryptocurrencies: Community, Economics, and Politics Alt...
Stanford CS251: Lecture 19
Apr 01, 2019
Lecture 19: Advanced Topics Topic 1: Smart Property Manage ownership of some property like stocks on the blockchain. Colored coins allow arbitrary properties on Smart Contract. Similar to Namecoin, th...
Stanford CS251: Lecture 18
Apr 01, 2019
Lecture 18: Advanced Topics Three topics are chosen by students (another three for the next lecture) Topic 1: Quantum Computing An electron has two states top and bottom spins, represented as |1> a...
Stanford CS251: Lecture 16
Apr 01, 2019
Lecture 16: Bitcoin payment channel Visa ~ 10, 000 transactions per second Bitcoin ~ 3 transactions per second => 60 GB of blockchain data per year Waiting for 6 blocks ~ 60 mins is a huge wait for...
Stanford CS251: Lecture 15
Apr 01, 2019
Lecture 15: Bitcoin guest talk (Greg Maxwell & Pieter Wuille - Blockstream) on sidechains Forking does not advance Bitcoin since forks suffer from economic acceptance. UTXO model UTXO model is les...
Stanford CS251: Lecture 13
Apr 01, 2019
Lecture 13 - Ethereum Code: ROM (Read-only memory) calldata: arguments There are two types of instructions: Arithmetic including SHA3 and sys operations like create [contract], call [contract], and de...
Stanford CS251: Lecture 14
Apr 01, 2019
Lecture 14: Ethereum Governance When contracts call other contracts, there are four major parameters, g - gas, v - value, in - in size of inputs, out - out size of outputs. The gas must come from the ...
Stanford CS251: Lecture 12
Apr 01, 2019
Recap: alt-coins Bitcoin is a replicated state machine, the system moves within S States with I inputs producing O outputs. For Bitcoin, S is the set of UTXOs. For Namecoin, the state consists (name, ...
Stanford CS251: Lecture 11
Apr 01, 2019
Lecture 11: Altcoins Three ways to improve Bitcoin Code update - This can update or change the P2P network Soft fork - To introduce a stricter verification for example P2SH Hard fork - transaction imp...
Stanford CS251: Lecture 10
Apr 01, 2019
Lecture 10: Anonymity on Blockchain (Coinjoin continued from the previous lecture) Each participant writes an input transaction (input address, change address) on say Pastebin. Over Tor, each particip...
Stanford CS251: Lecture 9
Apr 01, 2019
Lecture 9: Wallet & Anonymity Wallet A user has a lot of bitcoin address, each of which is H(p_k) or H(script). A wallet manages p_k/s_k, post/verify transactions, and show balances. A wallet can ...
Stanford CS251: Lecture 8
Apr 01, 2019
Lecture 8 - Alternative consensus Puzzle solutions are probabilistic proof of work. A typical puzzle utilization function can be modeled as P(challenge, randomness - nonce, difficulty, …) ->...
Stanford CS251: Lecture 7
Apr 01, 2019
Lecture 7: Community, Economics, and Politics David Chaum - digital cash in 1981 Satoshi Nakamoto - Oct 2008, bitcoin.org was registered in Aug 2008 Genesis block was mined in Jan 2009 First BTC payme...
Stanford CS251: Lecture 6
Apr 01, 2019
Lecture 6: Bitcoin Miner interactions and Game Theory Game Theory: P x S -> R x P P: Players S: Strategies R: Rewards Examples For the prisoner’s dilemma, tit-for-tat with some positive rando...
Stanford CS251: Lecture 5
Apr 01, 2019
Lecture 5: Bitcoin mining How to mine Bitcoin Download and run Bitcoin-core to run full Bitcoin node Listen for a new transaction, assemble a pre-block Solve the puzzle (~270 attempts) Broadcast the b...
Stanford CS251: Lecture 4
Apr 01, 2019
Lecture 4: Blockchains 80 bytes block consists of 32 bytes previous block hash, 32 bytes transactions Merkle tree hash, timestamp, bits, nonce, etc. Each block is <= 1MB to minimize the propagation...
Stanford CS251: Lecture 3
Apr 01, 2019
Lecture 3: Bitcoin overview There are three Bitcoin protocols Consensus Protocol - decides what the ledger is Transaction Protocol - assigns meaning to the ledger Network Protocol - the P2P protocol w...
Stanford CS251: Lecture 2
Apr 01, 2019
Lecture 2: Creating a digital currency Desirable properties of a good digital ledger No deletion Temporal ordering Global consensus Semantic correctness Live - writable, no DOS, no censorship Attempts...
Stanford CS251: Lecture 1
Apr 01, 2019
Lecture 1: Introduction Bitcoin is a cryptocurrency with distributed trust. The blockchain is a public append-only ledger. The append-only property is sufficient for having a currency. Hash functions:...
Android: Fragment related pitfalls and how to avoid them
Feb 09, 2019
Don’t use platform fragments (android.app.Fragment), they have been deprecated and can trigger version-specific bugs. Use the support library fragments ( android.support.v4.app.Fragment) instea...
Android: Handling JPEG images with Exif orientation flags
Jan 22, 2019
A JPEG file can have Exif metadata which can provide the rotation/translation field information for a raw JPEG image. So, a landscape raw JPEG image could actually be a portrait because it’s EXI...
Mac OS: App Translocation and Android Studio updates failure
Dec 01, 2018
I installed Android Studio via homebrew “brew cask install android-studio” as a part of my automated Mac OS setup. Recently, Android Studio prompted me that an update is available. When I ...
Cross-language bridge error handling: JS-to-Java Example
Nov 02, 2018
All languages have certain semantics for dealing with error cases. C deals with them by setting error codes. Java deals with them by throwing exceptions. JavaScript deals with them by throwing excepti...
Testing resumable uploads
Oct 06, 2018
The core idea behind resumable upload is straightforward if you are uploading a big file, then you are going to encounter users in the network conditions where they cannot upload the file in a single ...
How to speed up HTML5 videos
Aug 18, 2018
Some video streaming websites like YouTube provides an option for speeding up/slowing down videos; some don’t. The trick is simple, find out the Video object via Js 1 document.querySelector("...
Architecting Android apps for emerging markets
Aug 01, 2018
This is a long post. It covers several decisions like API version, distribution beyond play store, UI & network performance, and minimizing RAM, disk, and battery usage....
adb-enhanced: A swiss army knife for Android development
Jun 23, 2018
Android development requires tons of disconnected approaches for development and testing. Consider some scenarios To test runtime permission - Go to Settings -> Applications -> Application info...
Swift, Kotlin, and Go
Jun 20, 2018
It is impressive to see the amount of similarity which exists in Swift, Kotlin and Go, the three new languages for iOS, Android, and server-development respectively. Consider a simple, Hello World pro...
Android: The right way to pull SQLite database
May 01, 2018
Here’s the proper way to pull an application’s SQLite database from an Android device....
Diagnosing Mac apps which won't open (error -10810)
Dec 22, 2017
Occasionally, my mac applications end up in a corrupt state where they won’t open. I recently encountered this with Deluge. The first step to diagnose is to open Terminal and open them in the te...
Java Musings - referencing an uninitialized final variable
Oct 01, 2017
Java has fewer quirks compared to C++, but sometimes I do come across surprises. A code like following will fail to compile since you are trying to initialize a variable with an uninitialized variable...
Demystifying Android rendering: Jank and ANR
Sep 09, 2016
Almost everyone developing an Android app has seen something like this in their device logs. Bash 1 I/Choreographer(1200): Skipped 60 frames! The application may be doing too much work on its main thr...
Built-in "Developer options" in Android
Sep 04, 2016
Android has a few good settings built right into the platform for debugging under a hidden “Developer Options” menu. You can turn them on via Settings -> About Phone -> Build Number ...
Floating point in user-facing strings
Jun 25, 2016
%f in user-facing strings is dangerous. Depending on the architecture, programming language involved, version of that language and compiler optimization flags, results can vary slightly. And if there...
Tabs vs spaces for code indentation
May 22, 2016
One argument which some people might give in favor of using tabs is that it allows the viewer to decide how the code should appear to them. And hence, it separates the logic (indentation) from its app...
File size should always be of "long" type
May 21, 2016
Java 1 2 3 int getTextFileSize(String fileName) { return (int) (new File(BASE_DIR, fileName).length(); // WRONG } A 32-bit signed int can deal with ~2GB worth of data. And if your code is not going t...
My rm -rf moment
May 06, 2016
Yes, it did happen, and no, I am not stupid enough to execute rm -rf *. It was a bit more convoluted than that. I was trying to prepare a customized SD card image for the Android emulator. The fastest...
Mac OS X Primer (Part 3) - Window Management
Aug 23, 2015
Default window management scheme in Mac OS X is not well-polished. For example, till Mac OS 14.6, there is no way to make an application occupy left half of the screen or to make an application always...
Android command-line: gradle and testing
Jan 03, 2015
For android projects, some engineers use Android Studio (new), some use Eclipse with ADT (old), few like me still savor command line, this blog post is about handling (building, installing and testing...
How to start locale settings activity on android from command-line
Aug 18, 2014
A useful and handy command specially when you during experimentation, you are stuck because of a changing language settings to an undecipherable foreign language. Bash 1 adb shell am start -n 'com...
Android, Gradle and compile-time only dependencies
Aug 09, 2014
Android plugin for Gradle does not support Java-style compile time only dependencies. After spending a few hours on trying to build android app targeted for Amazon SDK (without using Amazon’s An...
Mac OS X Primer (Part 2): GNU/Linux -> Mac for software engineers
Feb 28, 2014
Booting process The bootloader loads the kernel stored in /mach_kernel. Tip: Use rEFIt as a bootloader for dual booting into GNU/Linux. Kernel launches the launchd process which is equivalent of init ...
How to compile android emulator on ubuntu 13.10
Feb 23, 2014
I was trying to make some modifications to android emulator and was unable to find good set of instructions for the compiling the same. Here are mine. Bash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Get the s...
How to send HTML mails using Amazon SES (Simple Email Service)
Feb 04, 2014
As the title suggests, I was looking for a way to send HTML mails in python using Amazon SES but did not find anything (or maybe my search skills are bad). So, once I found the solution, I thought I m...
Github 101 for hackathons
Dec 31, 2013
This blog post is a HOWTO guide for using github while collaborating during hackathons. It does not cover git in detail....
Mac OS X Primer: GNU/Linux -> Mac for software engineers
Dec 18, 2013
This blog post contains a collection of small tips for engineers migrating from GNU/Linux to Mac OS X for software development. Note: In another post, I wrote about why there is a dearth of a good GNU...
How to upgrade Nexus 4 to Android 4.4 Kitkat
Nov 15, 2013
Some experience with adb and fastboot preferred (they are part of android SDK)...
Understanding Directory Permissions on Linux
Jul 11, 2010
This blog post is for those who understand how file permissions work but are looking for an explanation on how file permissions behave when they are applied to directories....
Animation in diagrams (presentations in Latex)
Jun 18, 2010
While most people draw diagrams in Xfig (or GIMP) and include them in LaTeX, they can be drawn directly in LaTeX (using tikz package). A major advantage of doing that is animation (\pause) is possible...
Basic GDB Tutorial
May 31, 2010
So, you believe there are bugs in your C/C++ code or you have encountered SEGFAULT while executing your code. What will you do? write a lot of printf statements at various places in your code under su...
Programming in Linux for newbies
May 31, 2010
This is meant to be a small guide (though not exhaustive) for students beginning to program on Linux system. Particularly for those, who have done extensive C/C++ programming in Windows, using the Bor...
GCC Hacks
May 31, 2010
A small list of GCC Hacks g++ -o helloworld helloworld.cc produces helloworld binary from helloworld.cc C++ file. use -Wall switch turns on all warnings(potential errors) in the code (like unused vari...
‹
›
Following is a list of selected posts, all posts can be seen here. About me can be seen here.
Programming
- Ship tools as standalone static binaries
- Maintaining an Android app is a lot of work
- FastAPI vs Flask performance comparison
- How to run Python in production
- It is hard to recommend Python in production
Tech Thoughts
- Google Search is losing to Perplexity
- Continuous integration ≠ Continuous delivery
- World's simplest project success heuristic
- Temu and the Chinese approach
- Minimize Javascript in your codebase
Book Summaries
- Book Summary: One up on Wall Street by Peter Lynch
- Book summary: Sick Societies by Robert B. Edgerton
- Book Summary: Safe Haven by Mark Spitznagel
- Notable quotes from "How to Live" by Derek Sivers
- Book Summary: What I learned losing a million dollars by Jim Paul
Travel
- Two days in Tallinn, Estonia
- Two days in Helsinki, Finland
- Two days in Oslo, Norway
- Two days in Dublin, Ireland
- London in 5 days