Founder @UiltraHQ • Software Engineer • Building in public, learning & sharing.

Lagos, Nigeria
Hi, I'm Funso, a software engineer passionate about building products that solve real problems. I'm currently building Uiltra, a multi-tenant SaaS platform that brings together: ✍🏽 A Blog Engine 🎨 A Website Builder 🛒 An E-commerce Platform Instead of switching between multiple tools, the goal is to give creators and businesses one platform to publish content, build websites, and sell online. Here's a preview of the Blog Engine, now about 80% complete. Built with: • Django REST Framework • Angular Current features include: • Live editor with real-time preview • SEO metadata • Reading time & word count • A clean, distraction-free writing experience I'm building Uiltra in public and sharing the journey—from architecture decisions and coding challenges to product development and startup lessons. If you're interested in software engineering, SaaS, startups, AI, or building products from scratch, I'd love to have you along for the journey.
3
3
42
2,886
One of the hardest lessons in software engineering: The code that works isn't necessarily the code that's finished. You still have to think about: • failure • retries • concurrency • observability • security • migrations • backups “Works on my machine” is where engineering usually begins.
7
Distributed systems teach you a painful rule: Anything that can fail eventually will. Networks timeout. Messages arrive twice. Services restart. Databases become unavailable. Clocks disagree. Good systems aren't designed around the assumption that everything works. They're designed around what happens when it doesn't.
17
A database query being “fast” doesn't mean it's efficient. If your query returns 10 rows but scans 10 million, you got lucky. Indexes, query plans, cardinality, and the amount of data touched matter more than how quickly it happened on your laptop. Production exposes the difference.
18
A recommendation service tracked "already seen" items in a list and checked membership on every request fine at 100 items, a measurable slowdown at 100,000. Switching the check to a Set fixed the incident without touching any other code.
22
Most languages implement object property lookup using a hash table under the hood. That's why `obj.property` and `obj['property']` are typically O(1) instead of scanning through every property one by one.
18
When you're asked to design a system with fast lookups, fast insertion, and ordered iteration, you're really being asked which collection's trade-offs match the requirements. That's the actual skill hiding inside a "which data structure" question.
37
An object is a filing cabinet with labeled folders, not a single document. You don't "read the cabinet" you look up a specific folder by its label and get back exactly what's inside it, nothing more.
35
A bug where duplicate entries kept appearing turned out to be objects added to a Set that used reference equality, not value equality. Two objects with identical data were still "different" because they weren't the exact same reference in memory.
2
33
Beginners check if an object is empty with `if (obj)`, which is always true for any object, even `{}`. An empty object is still truthy. You need `Object.keys(obj).length === 0` to actually check for emptiness.
33
Iterating a Map or Set in most modern languages preserves insertion order. You often don't need a separate array just to remember "the order things were added" check your language's guarantees before building extra structure you don't need.
27
People think copying an object with `{...obj}` fully duplicates it. It only copies one level deep. Nested objects and arrays inside are still shared by reference. Change a nested property on the "copy" and the original changes too.
21
A LinkedList gives you O(1) insertion at any known position but O(n) access by index. An array gives you the opposite. Collections aren't "good" or "bad" they're a menu of trade-offs, and picking one is picking which operation you're willing to make slow.
29
In JavaScript, arrays are just objects with numeric keys and a special `length` property that updates automatically. `typeof []` is `"object"` for a reason there's no separate array data type, just an object pretending to be one.
3
46
Strings are immutable in Python, Java, and JavaScript. Every "modification" like `s += "x"` actually creates a brand-new string in memory and discards the old one. Concatenating in a loop a million times means creating a million throwaway strings.
25
Arrays give you O(1) access by index but O(n) insertion in the middle. Linked lists give you the opposite. Neither is "better" you're choosing whether you read more or insert more, and that choice should come from your actual usage pattern, not habit.
27
People think a string's length equals its character count. In Unicode, some emoji take up two or more "code units," so `"😀".length` is 2 in JavaScript, not 1. Counting characters correctly requires knowing about grapheme clusters, not just `.length`.
31
Preallocating an array to its known final size, instead of growing it one `push()` at a time, avoids repeated reallocation and copying. It's a one-line change that can meaningfully speed up large data processing loops.
20
Building a large string with `result += piece` inside a loop is a classic beginner performance trap. Each concatenation allocates a new string. Using a string builder or array-join pattern instead can be an order of magnitude faster.
21
A bug that only appeared with large inputs turned out to be an array mutated while it was being iterated over. Removing an element during a `forEach` loop shifts every subsequent index, silently skipping the next item.
26
A string is a printed book, not a whiteboard. You can't edit a page in place you have to print an entirely new book with the change. That's why "mutating" a string in most languages secretly means creating a whole new one.
1
1
41