Live data from Hacker News

I run multiple $10K MRR companies on a $20/month tech stack

stevehanov.ca

451–460 of 539 posts

Re: I run multiple $10K MRR companies on a $20/month tech stack

#451

Earlier quoted context omitted.

No offense, you wait. Like everyone's been doing for years in the internet and still do - When AWS/GCP goes down, how do most handle HA? - When a database server goes down, how do most handle HA? - When Cloudflare goes down, how do most handle HA? The down time here is the server crashed, routing failed or some other issue with the host. You wait. One may run pingdom or something to alert you.

> When AWS/GCP goes down, how do most handle HA? This is a disingenuous scenario. SQLite doesn't buy you uptime if you deploy your app to AWS/GCP, and you can just as easily deploy a proper RDBMS such as postgres to a small provider/self-host. Do you actually have any concrete scenario that supports your belief?

All I'm saying is that people mention HA, when there isn't a need for it or when most people are fine with some downtime. For example,

> When AWS/GCP goes down, how do most handle HA?

When they go down, what do most do? Honestly, people still go about their day and are okay. Look how many systems do go down. What ends up happening? An article goes out that X cloud took out large parts of the internet.. and that's it.

Even when there's ways of doing it, they just go down and we accept it. I never said this doesn't go down or can't go down, it's just that it's okay and totally fine if it does.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#452

> If you need a little breathing room, just use a swapfile. You should always use a swap file/partition, even if you don't want any swapping. That's because there are always cold pages and if you have no swap space that memory cannot be used for apps or buffers, it's just wasted.

People seem to be using zram today. Maybe not on servers.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#453

Earlier quoted context omitted.

If I give you a box with 1 GiB of RAM, you are literally forced to either optimize your code to run in it, or accept the slowdown from paging. How is this specious?

Why not a box with 128MB of RAM then?

Aside from the perfect solution fallacy, pragmatically it's because most operating systems require more than that to run. Debian's current recommended minimum is 512 MB, though they note that with swap enabled, as little as 350 MB is possible. If you wanted to run something more esoteric like Damn Small Linux, it's possible with as little as 64 MB last I checked.

In any case, this is for the OS itself - the webserver, application, database, etc. will all of course require their own. For a well-optimized program with a well-optimized schema, 1 GB is a reasonable lower bound.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#454

Earlier quoted context omitted.

Sqlite smokes postgres on the same machine even with domain sockets [1]. This is before you get into using multiple sqlite database. What features postgres offers over sqlite in the context of running on a single machine with a monolithic app? Application functions [2] means you can extend it however you need with the same language you use to build your application. It also has a much better backup and replication st…

I've slowly evolved from just writing to and looking up json files to using SQLite, since I had to do a bit more advanced querying. I'm glad I did. But the defaults did surprise me! I'm using it with php, and I noticed some inserts were failing. Turns out there's no tolerance for concurrent writes, and there's no global config that can be changed. Rertry/timeout has to be configured per connection. I'm still not sure…

This is the fault/price of backwards compatibility. Most users of SQLite should just fire off a few pragmas on each connection:

    PRAGMA journal_mode = WAL
    PRAGMA foreign_keys = ON
    # Something non-null
    PRAGMA busy_timeout = 1000
    # This is fine for most applications, but see the manual
    PRAGMA synchronous = NORMAL
    # If you use it as a file format
    PRAGMA trusted_schema = OFF
You might need additional options, depending on the binding. E.g. Python applications should not use the defaults of the sqlite3 module, which are simply wrong (with no alternative except out-of-stdlib bindings pre-3.12): https://docs.python.org/3/library/sqlite3.html#transaction-c...

Also use strict tables. https://www.sqlite.org/stricttables.html

Re: I run multiple $10K MRR companies on a $20/month tech stack

#455

Lots of debate about SQLite vs Postgres. One thing to note is you can certainly run Postgres (Kubernetes even if you want) and your app for $20 / month.

A $20 k8s sounds like adding the overhead without the benefits.

It's about 300MiB and maybe 5% of a core if the cloud provider offers a free managed control plan. If you want / like Kubernetes it isn't a deal breaker.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#457
post #117
post #67

Earlier quoted context omitted.

It is true, it's the official pricing of GitHub Copilot.

Why is GitHub sticking to per-request pricing when other providers switched to per-token for the high performing models?

More likely loss leader to market capture. Not unusual for MSFT. XBox One, Razor and Blade, etc.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#458

Earlier quoted context omitted.

Thank you for clarification, I was wrong in my prev comment. > - [1] An interactive transaction is a transaction where you intermingle database queries and application logic (running on the application). could you give specific example why do you think SQlite can do batching and PG not?

An interactive transaction works like this in pseudo code. beginTx // query to get some data (network hop) result = exec(query1) // application code that needs to run in the application safeResult = transformAndValidate(result) // query to write the data (network hop) exec(query2, safeResult) endTx How would you batch this in postgres and get any value? You can nest them all in a single transaction. But, because they…

> How would you batch this in postgres and get any value? You can nest them all in a single transaction. But, because they are interactive transactions that doesn't reduce your number of network hops.

you can write it as stored procedure in your favorite language, or use domain socket where communication happens using through shared memory buffs without network involved.

In your post, I think big performance hit for postgres potentially comes from focus on update only statement, in SQlite updates likely happen in place, while postgress creates separate record on disk for each updated record, or maybe some other internal stuff going on.

Your benchmark is very simplistic, it is hard to tell what would be behavior of SQlite if you switch to inserts for example, or many writers which compete for the same record, or transaction would be longer. Industry built various benchmarks for this, tpc for example.

Also, if you want readers understand your posts better, you can consider using less exotic language in the future. Its hard to read what is and how is batched there.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#459

Earlier quoted context omitted.

In your example, clients can't have their own transactions? You commit/rollback all requests for all 1000 clients together?

Sqlite supports nested transactions with SAVEPOINT so each client can have their own logical transaction that can be rolled back. The outer transaction just batches the fsync effectively. So an individual client failing a transaction doesn't cause the batch to fail. But, a crash would cause the batch to fail. Because, it's a single writer, there's no rollback/retries from contention/MVCC. You could try to imitate thi…

so, in sqlite you need to write some app code to batch transactions in the app, so it has non-trivial development and maintenance cost.

Re: I run multiple $10K MRR companies on a $20/month tech stack

#460
post #376

Earlier quoted context omitted.

Why go live if you don't have a reasonable expectation of users? Worrying about HA when you don't have customers that need it is one thing, but I wouldn't want to be in a place where I have to put a banner on the website asking users to please make a new account because we had an oopsie.

To be fair, there's a big difference between "we do periodic backups" and "we can restore to any millisecond since product launch.

Sure, but it seemed to be that any backups at all were being called too frivolous.
Post reply on HN