davideisinger.com

My personal website
Log | Files | Refs | README

benhoyt-com-vfdv1s.txt (37074B)


      1 [1]Ben Hoyt
      2 
      3   • [2]Home
      4   • [3]Resume/CV
      5   • [4]Projects
      6   • [5]Tech Writing
      7   • [6]Non-Tech
      8   • [7]Email
      9 
     10   • [8]benhoyt.com
     11   • [9][email protected]
     12 
     13 The small web is beautiful
     14 
     15 March 2021
     16 
     17     Summary: I believe that small websites are compelling aesthetically, but
     18     are also important to help us resist selling our souls to large tech
     19     companies. In this essay I present a vision for the “small web” as well as
     20     the small software and architectures that power it. Also, a bonus rant
     21     about microservices.
     22 
     23     Go to: [10]Software | [11]Web | [12]Server-side | [13]Static sites | [14]
     24     Dependencies | [15]Analytics | [16]Microservices
     25 
     26 About fifteen years ago, I read E. F. Schumacher’s Small is Beautiful and,
     27 despite not being interested in economics, I was moved by its message. Perhaps
     28 even more, I loved the terse poetry of the book’s title – it resonated with my
     29 frugal upbringing and my own aesthetic.
     30 
     31 I think it’s time for a version of that book about technology, with a chapter
     32 on web development: The Small Web is Beautiful: A Study of Web Development as
     33 if People Mattered. Until someone writes that, this essay will have to do.
     34 
     35 There are two aspects of this: first, small teams and companies. I’m not going
     36 to talk much about that here, but [17]Basecamp and many others have. What I’m
     37 going to focus on in this essay is small websites and architectures.
     38 
     39 I’m not the first to talk about the “small web”, but, somewhat surprisingly,
     40 only a few people have discussed it using that term. Here are the main web
     41 pages I can find that do:
     42 
     43   • [18]Rediscovering the Small Web by Parimal Satyal: a fabulous article about
     44     the joy of small, independent (and sometimes retro) websites in contrast to
     45     the “commercial web”.
     46   • [19]What is the Small Web?, by Aral Balkan of the Small Technology
     47     Foundation: more of a manifesto against the surveillance of Big Tech than
     48     something concrete, but still interesting.
     49 
     50 Why aim small in this era of fast computers with plenty of RAM? A number of
     51 reasons, but the ones that are most important to me are:
     52 
     53   • Fewer moving parts. It’s easier to create more robust systems and to fix
     54     things when they do go wrong.
     55   • Small software is faster. Fewer bits to download and clog your computer’s
     56     memory.
     57   • Reduced power consumption. This is important on a “save the planet” scale,
     58     but also on the very local scale of increasing the battery life of your
     59     phone and laptop.
     60   • The light, frugal aesthetic. That’s personal, I know, but as you’ll see,
     61     I’m not alone.
     62 
     63 So let’s dive in. I want to cover a bunch of different angles, each with its
     64 own subheading.
     65 
     66 Small software
     67 
     68 If we’re going to talk about a small web, we need to start with small software.
     69 
     70 As a teen, I learned to program using x86 assembly and [20]Forth – perhaps odd
     71 choices, but my dad was heavily into Forth, and I loved how the language was so
     72 simple I could write [21]my own bootstrapped compiler.
     73 
     74 In terms of career, I started as an embedded programmer – not as in “embedded
     75 Linux” but as in microcontrollers where 16KB of RAM was generous. My current
     76 laptop has 16GB of RAM, and that’s not a lot by today’s standards. We were
     77 building IP-networked products with one millionth the amount of RAM. Those
     78 kinds of micros are as cheap as chips (ahem), and still widely used for small
     79 electronic devices, sensors, internet-of-things products, and so on.
     80 
     81 You have to think about every byte, compile with size optimizations enabled,
     82 and reuse buffers. It’s a very different thing from modern web development,
     83 where a JavaScript app compiles “down” to a 1MB bundle, or a single Python
     84 object header is 16 bytes before you’ve even got any data, or a Go hello-world
     85 binary is 2MB even before you’ve added any real code.
     86 
     87 How do you create small programs? I think the main thing is that you have to
     88 care about size, and most of us don’t think we have time for that. Apart from
     89 embedded development, there’s an entire programming subculture called the [22]
     90 demoscene that cares about this. They have competitions for the smallest 4KB
     91 demos: who can pack the most graphical punch into 4096 bytes of executable.
     92 That’s smaller than many favicons! ([23]Elevated and [24]cdak are two of the
     93 highest-rated 4K demos.) Many demosceners go on to become game developers.
     94 
     95 It’s not just about executable size … when you’re developing your next command
     96 line tool, if you use Go or Rust or even C, your program will be much faster,
     97 smaller, and use less memory than a Python or Java equivalent. And easier to
     98 install. If you don’t understand why, please do learn. (It’s out of scope for
     99 this essay, but to summarize: Go, Rust, and C compile to ready-to-execute
    100 machine code, don’t carry around a virtual machine, and don’t have memory
    101 overhead for objects like integers.)
    102 
    103 But why not apply some of the same principles to web development? In the web
    104 world, I think the main trick is to be careful what dependencies you include,
    105 and also what dependencies they pull in. In short, know node_modules – or maybe
    106 better, no node_modules. More about this [25]below.
    107 
    108 Niklaus Wirth of Pascal fame wrote a famous paper in 1995 called [26]A Plea for
    109 Lean Software [PDF]. His take is that “a primary cause for the complexity is
    110 that software vendors uncritically adopt almost any feature that users want”,
    111 and “when a system’s power is measured by the number of its features, quantity
    112 becomes more important than quality”. He goes on to describe Oberon, a computer
    113 language (which reminds me of Go in several ways) and an operating system that
    114 he believes helps solve the complexity problem. Definitely wirth a read!
    115 
    116 I’ve been mulling over this for a number of years – back in 2008 I wrote a
    117 sarcastic dig at how bloated Adobe Reader had become: [27]Thank you, Adobe
    118 Reader 9! It was a 33MB download and required 220MB of hard drive space even in
    119 2008 (it’s now a 150MB download, and I don’t know how much hard drive space it
    120 requires, because I don’t install it these days).
    121 
    122 But instead of just complaining, how do we actually solve this problem?
    123 Concretely, I think we need to start doing the following:
    124 
    125   • Care about size: this sounds obvious, but things only change when people
    126     think they’re important.
    127   • Measure: both your executable’s size, and your program’s memory usage. You
    128     may want to measure over time, and make it a blocking issue if the
    129     measurements grow more than x% in a release. Or you could hold a
    130     memory-reduction sprint every so often.
    131   • Language: choose a backend language that has a chance, for example Rust, C
    132     or C++, or for servers, Go. These languages aren’t right for everything
    133     (like data transformation scripts), but they produce small executables, and
    134     they’re good for CLIs and desktop apps.
    135   • Remove: cut down your feature set. Aim for a small number of high-quality
    136     features. My car can’t fly or float, and that’s okay – it drives well.
    137   • Say no to new features: unless they really fit your philosophy, or add more
    138     than they cost over the lifetime of your project.
    139   • Dependencies: understand the size and complexity of each dependency you
    140     pull in. Use only built-in libraries if you can.
    141 
    142 Small websites
    143 
    144 I’m glad there’s a growing number of people interested in small websites.
    145 
    146 A few months ago there was a sequence of posts to Hacker News about various
    147 “clubs” you could post your small website on: the [28]1MB Club ([29]comments), 
    148 [30]512KB Club ([31]comments), [32]250KB Club ([33]comments), and even the [34]
    149 10KB Club ([35]comments). I think those are a fun indicator of renewed
    150 interested in minimalism, but I will say that raw size isn’t enough – a 2KB
    151 site with no real content isn’t much good, and a page with 512KB of very slow
    152 JavaScript is worse than a snappy site with 4MB of well-chosen images.
    153 
    154 Some of my favourite small websites are:
    155 
    156 [36]Hacker News: I personally like the minimalist, almost brutalist design, but
    157 I love its lightness even more. I just downloaded the home page, and loading
    158 all resources transfers only 21KB (61KB uncompressed). Even pages with huge
    159 comment threads only transfer about 100KB of compressed data, and load quickly.
    160 Reddit has become such a bloated mess in comparison. Hacker News, never change!
    161 
    162 [37]Lobsters: a similar news-and-voting site, with slightly more “modern”
    163 styling. It uses some JavaScript and profile icons, but it’s still clean and
    164 fast, and the total transfer size for the homepage is only 102KB. You just
    165 don’t need megabytes to make a good website.
    166 
    167 [38]Sourcehut: I like the concept behind Drew DeVault’s business, but I love
    168 how small and anti-fluff the website is. He has set up a mini-site called the 
    169 [39]Software Forge Performance Index that tracks size and browser performance
    170 of the prominent source code websites – Sourcehut is far and away the lightest
    171 and fastest. Even his homepage is only 81KB, including several screenshot
    172 thumbnails.
    173 
    174 [40]SQLite: not only is SQLite a small, powerful SQL database engine, the
    175 website is fantastically small and content-rich. Even their 7000-word [41]page
    176 about testing is only 70KB. How do they do this? It’s not magic: focus on
    177 high-quality textual content, minimal CSS, no JavaScript, and very few images
    178 (a small logo and some SVGs).
    179 
    180 [42]LWN: I’m a little biased, because I’ve written [43]articles for them, but
    181 they’re an excellent website for Linux and programming news. Extremely
    182 high-quality technical content (and a high bar for authors). They’re definitely
    183 niche, and have a “we focus on quality content, not updating our CSS every
    184 year” kind of look – they’ve been putting out great content for 23 years! Their
    185 homepage only downloads 44KB (90KB uncompressed).
    186 
    187 [44]Dan Luu’s blog: this is one of the more hardcore examples. His inline CSS
    188 is only about 200 bytes (the pages are basically unstyled), and his HTML source
    189 code doesn’t use any linefeed characters. Kind of a fun point, although then he
    190 goes on to load 20KB of Google Analytics JavaScript…
    191 
    192 As a friend pointed out, those websites have something of an “anti-aesthetic
    193 aesthetic”. I confess to not minding that at all, but on the other hand, small
    194 doesn’t have to mean ugly. More and more personal blogs and websites have
    195 adopted a small web approach but are more typographically appealing:
    196 
    197   • [45]Armin Ronacher’s Thoughts and Writings
    198   • [46]Chris Wellons’ “Null program” blog
    199   • [47]Eric Radman’s BSD and SQL blog
    200   • [48]Hugo Tunius’ programming blog
    201   • [49]James Hague’s “Programming in the Twenty-First Century”
    202   • [50]Julia Evans’ programming blog
    203 
    204 There are many, many more. Programmer Sijmen Mulder created a nice list of [51]
    205 text-only websites – not quite the same thing as small, but it definitely
    206 overlaps!
    207 
    208 However, it’s not just about raw size, but about an “ethos of small”. It’s
    209 caring about the users of your site: that your pages download fast, are easy to
    210 read, have interesting content, and don’t load scads of JavaScript for Google
    211 or Facebook’s trackers. Building a website from scratch is not everyone’s cup
    212 of tea, but for those of us who do it, maybe we can promote templates and tools
    213 that produce small sites that encourage quality over quantity.
    214 
    215 For this website, I lovingly crafted each byte of HTML and CSS by hand, like a
    216 hipster creating a craft beer. Seriously though, if your focus is good content,
    217 it’s not hard to create a simple template from scratch with just a few lines of
    218 HTML and CSS. It will be small and fast, and it’ll be yours.
    219 
    220 Loading this essay transfers about 23KB (56KB uncompressed), including the
    221 favicon and analytics script. It’s small, fast, and readable on desktop or
    222 mobile. I don’t think it’s too bad looking, but I’m primarily aiming for a
    223 minimalist design focussed on the content.
    224 
    225 In addition to making sure your HTML and CSS are small, be sure to compress
    226 your images properly. Two basic things here: don’t upload ultra-high resolution
    227 images straight from your camera, and use a reasonable amount of JPEG
    228 compression for photos (and PNG for screenshots or vector art). Even for large
    229 images, you can usually use 75% or 80% compression and still have an image
    230 without JPEG noise. For example, the large 1920x775 image on the top of my [52]
    231 side business’s homepage is only 300KB.
    232 
    233 Speaking of hero images, you don’t need big irrelevant images at the top of
    234 your blog posts. They just add hundreds of kilobytes (even megabytes) to your
    235 page weight, and don’t provide value. And please don’t scatter your article
    236 with animated GIFs: if there’s something animated on the screen, I can hardly
    237 concentrate enough to read the text – and I’m [53]not the [54]only one. Include
    238 relevant, non-stock images that provide value equal to their weight in bytes.
    239 Bare text is okay, too, like a magazine article.
    240 
    241 [55]IndieWeb.org is a great resource here, though they use the term “indie”
    242 rather than “small”. This movement looks more organic than the [56]Small
    243 Technology Foundation (which has even been [57]critiqued as “digital
    244 green-washing”), and their wiki has a lot more real content. IndieWeb also
    245 promotes local [58]Homebrew Website Clubs and [59]IndieWebCamp meetups.
    246 
    247 Emphasize server-side, not JavaScript
    248 
    249 JavaScript is a mixed blessing for the web, and more often than not a bane for
    250 small websites: it adds to the download size and time, it can be a performance
    251 killer, it’s bad for accessibility, and if you don’t hold it right, it’s [60]
    252 bad for search engines. Plus, if your website is content-heavy, it probably
    253 isn’t adding much.
    254 
    255 Don’t get me wrong: JavaScript is sometimes unavoidable, and is great where
    256 it’s great. If you’re developing a browser-based application like Gmail or
    257 Google Maps, you should almost certainly be using JavaScript. But for your next
    258 blog, brochure website, or project documentation site, please consider plain
    259 HTML and CSS.
    260 
    261 If your site – like a lot of sites – is somewhere in between and contains some
    262 light interaction, consider using JavaScript only for the parts of the page
    263 that need it. There’s no need to overhaul your whole site using React and Redux
    264 just to add a form. Letting your server generate HTML is still an effective way
    265 to create fast websites.
    266 
    267 [61]Stack Overflow is a case in point. From day one, they’ve made [62]
    268 performance a feature by rendering their pages on the server, and by measuring
    269 and reducing render time. I’m sure the Stack Overflow code has changed quite a
    270 lot since the Jeff Atwood days – it now makes a ton of extra requests for
    271 advertising purposes – but the content still loads fast.
    272 
    273 [63]Hacker News (there’s that site again) is a server-side classic. With only 
    274 [64]one tiny JavaScript file for voting, the HTML generated on the server does
    275 the rest. And [65]apparently it still runs on a single machine.
    276 
    277 Around fifteen years ago there was this great idea called [66]progressive
    278 enhancement. The idea was to serve usable HTML content to everyone, but users
    279 with JavaScript enabled or fast internet connections would get an enhanced
    280 version with a more streamlined user interface. In fact, Hacker News itself
    281 uses progressive enhancement: even in 2021, you can still turn off JavaScript
    282 and use the voting buttons. It’s a bit clunkier because voting now requires a
    283 page reload, but it works fine.
    284 
    285 Is progressive enhancement still relevant in 2021? Arguably not, though some
    286 die-hards still turn JavaScript off, or at least enable it only for sites they
    287 trust. However, I think it’s the mentality that’s most important: it shows the
    288 developer cares about performance, size, and alternative users. If Hacker News
    289 voting didn’t work without JavaScript, I don’t think that would be a big
    290 problem – but it shows a certain kind of nerdish care that it does work. Plus,
    291 the JavaScript they do have is only 2KB (5KB uncompressed).
    292 
    293 Compare that to the 8MB (14MB uncompressed) that the [67]Reddit homepage loads.
    294 And this across 201 requests – I kid you not! – most of which is JavaScript to
    295 power all the ads and tracking. Lovely…
    296 
    297 You don’t need a “framework” to develop this way, of course, but there are some
    298 tools that make this style of server-side development easier. [68]Turbolinks
    299 from the Basecamp folks was an early one, and it’s now been superseded by [69]
    300 Turbo, which is apparently used to power their email service [70]Hey. I haven’t
    301 used these personally, but the ideas are clever (and surprisingly old-skool):
    302 use standard links and form submissions, [71]serve plain HTML, but speed it up
    303 with WebSockets and JavaScript if available. Just today, in fact, someone
    304 posted a new article on Hacker News which claims [72]“The Future of Web
    305 Software Is HTML-over-WebSockets”. If Hey is anything to go by, this technique
    306 is fast!
    307 
    308 On the other hand, sometimes you can reduce overall complexity by using
    309 JavaScript for the whole page if you’re going to need it anyway. For example,
    310 the registry pages on my wedding registry website are rendered on the client
    311 (they actually [73]use Elm, which compiles to JavaScript). I do need the
    312 interactivity of JavaScript (it’s more “single page application” than mere
    313 content), but I don’t need server-side rendering or good SEO for these pages.
    314 The homepage is a simple server-rendered template, but the registry pages are
    315 fully client-rendered.
    316 
    317 Static sites and site generators
    318 
    319 Another thing there’s been renewed interest in recently is static websites
    320 (these used to be called just “websites”). You upload some static HTML (and CSS
    321 and JavaScript) to a static file server, and that’s it.
    322 
    323 Improving on that, there are many “static site generators” available. These are
    324 tools that generate a static site from simple templates, so that you don’t have
    325 to copy your site’s header and footer into every HTML file by hand. When you
    326 add an article or make a change, run the script to re-generate. If you’re
    327 hosting a simple site or blog or even a news site, this is a great way to go.
    328 It’s content, after all, not an interactive application.
    329 
    330 I use [74]GitHub Pages on this site just because it’s a free host that supports
    331 SSL, and automatically builds your site using the [75]Jekyll static site
    332 generator whenever you push a change. I have a standard header and include the
    333 same CSS across all pages easily, though you can have multiple templates or
    334 “layouts” if you want. Because most people only view one or two articles on my
    335 site, I include my CSS inline. With HTTP/2, this doesn’t make much difference,
    336 but Lighthouse showed around 200ms with inline CSS, 300ms with external CSS.
    337 
    338 Here’s an example of what a simple Jekyll page looks like (the start of this
    339 essay, in fact):
    340 
    341     ---
    342     layout: default
    343     title: "The small web is beautiful"
    344     permalink: /writings/the-small-web-is-beautiful/
    345     description: A vision for the "small web", small software, and ...
    346     ---
    347     Markdown text here.
    348 
    349 I’ve also used [76]Hugo, which is a really fast static site generator written
    350 in Go – it generates even large sites with thousands of pages in a few seconds.
    351 And there are [77]many other options available.
    352 
    353 Fewer dependencies
    354 
    355 There’s nothing that blows up the size of your software (or JavaScript bundle)
    356 like third party dependencies. I always find a web project’s node_modules
    357 directory hard to look at – just the sheer volume of stuff in there makes me
    358 sad.
    359 
    360 Different languages seem to have different “dependency cultures”. JavaScript,
    361 of course, is notorious for an “if it can be a library, it should be” attitude,
    362 resulting in the [78]left-pad disaster as well as other minuscule libraries
    363 like the 3-line [79]isarray. There are also big, heavy packages like [80]
    364 Moment.js, which takes [81]160KB even when minified. There are ways to shrink
    365 it down if you don’t need all locales, but it’s not the default, so most people
    366 don’t (you’re probably better off choosing a more modular approach like [82]
    367 date-fns).
    368 
    369 Go now has good dependency management with the recent [83]modules tooling, but
    370 it also has a culture of “use the standard library if you can”. Russ Cox wrote
    371 an excellent essay about the downsides of not being careful with your
    372 dependencies: [84]Our Software Dependency Problem. Go co-creator Rob Pike even
    373 made this one of his [85]Go proverbs: “A little copying is better than a little
    374 dependency.” You can probably guess by now, but I like this minimalist
    375 approach: apart from reducing the number of points of failure, it makes
    376 programs smaller.
    377 
    378 Python, Ruby, Java, and C# seem to be somewhere in between: people use a fair
    379 number of dependencies, but from what I’ve seen there’s more care taken and it
    380 doesn’t get as out of hand as node_modules. Admittedly it is a little unfair,
    381 as Python (and those other languages) have standard libraries that have more in
    382 them than JavaScript’s.
    383 
    384 The website [86]YouMightNotNeedjQuery.com shows how many of the tasks you think
    385 you might need a library for are actually quite simple to do with plain
    386 JavaScript. For example, in one of my projects I use a function like the
    387 following to make an API request with plain old XMLHttpRequest:
    388 
    389 function postJson(url, data, callback) {
    390     var xhr = new XMLHttpRequest();
    391     xhr.onreadystatechange = function () {
    392         if (xhr.readyState === xhr.DONE) {
    393             callback(xhr.status, JSON.parse(xhr.responseText));
    394         }
    395     };
    396     xhr.open("POST", url, true);
    397     xhr.setRequestHeader("Content-Type", "application/json");
    398     xhr.send(JSON.stringify(data));
    399 }
    400 
    401 The moral of the story: think twice before adding dependencies. You’ll keep
    402 your websites and programs smaller and more reliable, and you’ll thank Russ Cox
    403 later.
    404 
    405 Small analytics
    406 
    407 Most website owners want some form of analytics to see how many visitors are
    408 coming to their site, and from where. The go-to tool is Google Analytics: it’s
    409 easy to set up and the UI is pretty comprehensive. But there’s a cost: it adds
    410 a significant amount of weight to your page (19KB of JavaScript, 46KB
    411 uncompressed), and it sends a lot of user data for Google to collect.
    412 
    413 Once again, there’s been renewed interest in smaller, more privacy-friendly
    414 analytics systems in recent times. Just this morning I read a provocative
    415 article that was highly-voted on Hacker News called [87]“Google Analytics: Stop
    416 feeding the beast”.
    417 
    418 Last year I wrote two articles for LWN on the subject, so I won’t say too much
    419 more here:
    420 
    421   • [88]Lightweight alternatives to Google Analytics: replacing it with
    422     lightweight open source and privacy-conscious alternatives, specifically 
    423     [89]GoatCounter and [90]Plausible.
    424   • [91]More alternatives to Google Analytics: some heavier alternatives, and a
    425     brief look at log-based analytics tools.
    426 
    427 For this website I use GoatCounter, which is available as a low-cost hosted
    428 service (free for non-commercial use) or as a self-hosted tool. I really like
    429 what Martin is doing here, and how small and simple the tool is: no bells and
    430 whistles, just the basic traffic numbers that most people want.
    431 
    432 Small architectures (not microservices)
    433 
    434 Small websites are great for users, but small architectures are great for
    435 developers. A small, simple codebase is easy to maintain, and will have fewer
    436 bugs than a large, sprawling system with lots of interaction points.
    437 
    438 I contend that the “microservices everywhere” buzz is a big problem.
    439 Microservices may be used successfully at Google and Amazon, but most companies
    440 don’t need to build that way. They introduce complexity in the code, API
    441 definitions, networking, deployment, server infrastructure, monitoring,
    442 database transactions – just about every aspect of a system is made more
    443 complex. Why is that?
    444 
    445   • Code: you have lots of little repositories, possibly in different
    446     languages, and each has to have some way to talk to the other services
    447     (JSON over HTTP, gRPC, etc). With a monolithic system, it’s all in one
    448     language (much better for a small team), calling other modules is just a
    449     function call, and system-wide refactoring is comparatively easy
    450     (especially in a statically typed language like Go or Java).
    451   • API definitions: with many services talking to each other, suddenly you
    452     need standardized interfaces for how they communicate. You spend a lot of
    453     time setting up gRPC or JSON schema definitions. In a single codebase, a
    454     function signature is the API definition.
    455   • Networking: with microservices, a function call is a network call, and you
    456     spend time setting up your network infrastructure, thinking about timeouts
    457     and retries, and maybe even designing inter-service authentication. In
    458     monolithic systems, you only worry about networking when talking to your
    459     database, cloud provider, and users.
    460   • Deployment: at a previous company I worked at, once we started building
    461     with microservices, suddenly we needed fancy deployment tooling and a
    462     dedicated infrastructure team to manage it all. You can get by with a lot
    463     less if you’re only deploying a few services.
    464   • Server infrastructure: you’ll probably need to set up new infrastructure –
    465     lots of small virtual machines, or a Kubernetes-based system. Kubernetes in
    466     itself is a complex distributed application (even [92]Google admits it’s
    467     too complex), and it takes a lot of work – or a lot of money – to run
    468     properly.
    469   • Monitoring: to debug issues, you’ll need costly distributed-monitoring
    470     software like Datadog to see what’s going on. When an outage occurs, you’ll
    471     scramble to determine which service is responsible, which team to page, and
    472     so on. Compare that with a simple stack trace or single-service issue.
    473   • Database transactions: these are difficult to impossible in a microservices
    474     architecture. You may be able to design your way out of them, but that’s
    475     not easy either. With a monolith, just type BEGIN ... COMMIT, or however
    476     your database library spells it.
    477 
    478 It’s been said before, but microservices solve a people problem, not a
    479 technical one. But beware of [93]Conway’s Law: your architecture will mimic
    480 your company structure. Or the reverse – you’ll have to hire and reorg so that
    481 your company structure matches the architecture that microservices require:
    482 lots of engineers on lots of small teams, with each team managing a couple of
    483 microservices.
    484 
    485 That doesn’t mean microservices are always the wrong choice: they may be
    486 necessary in huge engineering organizations. However, if you’re working at such
    487 a company, you’ve probably already been using microservices for years. If
    488 you’re not “Google size”, you should think twice before copying their
    489 development practices.
    490 
    491 What’s the alternative? The term “monolith” has a bad rap, but I agree with
    492 David at Basecamp that [94]monoliths can be majestic. Basecamp is a large,
    493 monolithic application, and they run it with just a dozen programmers. David is
    494 quick to point out that “the Majestic Monolith doesn’t pretend to provide a
    495 failsafe architectural road to glory”. You still have to think, design, and
    496 write good code.
    497 
    498 Thankfully, people are bouncing back from the cargo culting. Just do a search
    499 for [95]“why not microservices” and you’ll find lots of good articles on the
    500 subject. One of the recent ones I’ve read is from Tailscale: [96]Modules,
    501 monoliths, and microservices.
    502 
    503 So what’s my advice?
    504 
    505   • Unless your company name is Google or Amazon, start with a monolith.
    506   • Once it starts having problems, optimize or refactor the pain points.
    507   • If it’s still having issues, buy a bigger server.
    508   • If you have a specific technical reason to split it up, fix that problem.
    509   • If there are still problems, split off only the component that needs
    510     splitting off. You’ll have two services to deploy and monitor, but that’s
    511     far simpler than going all-in on microservices.
    512 
    513 Okay, so this became more of an anti-microservices rant than I was planning,
    514 but so be it.
    515 
    516 In terms of counter-examples, Stack Overflow once again comes to mind. They’re
    517 one of the web’s busiest sites, but they have a relatively simple, two-tier 
    518 [97]architecture that they’ve scaled vertically – in other words, big servers
    519 with lots of RAM, rather than hundreds of small servers. They have 9 web
    520 servers and 4 very chunky SQL servers, with a few additional servers for their
    521 tag engine, Redis, Elasticsearch, and HAProxy. This architecture helps them get
    522 great performance and the ability to develop with a small team.
    523 
    524 My own side business, [98]GiftyWeddings.com, only gets a small amount of
    525 traffic, so it’s nothing like Stack Overflow, but it uses a Go HTTP server with
    526 SQLite on one of the smallest EC2 instances available, [99]t2.micro. It costs
    527 about $8 per month, and I only have one tiny piece of infrastructure to
    528 maintain. I deploy using [100]Ansible – a tool that is another good example of
    529 simple architecture and boils down to “just use ssh”.
    530 
    531 Speaking of SQLite, there’s a growing number of developers who advocate using
    532 SQLite to run their websites. SQLite’s [101]“when to use SQLite” page says “any
    533 site that gets fewer than 100K hits/day should work fine with SQLite. The 100K
    534 hits/day figure is a conservative estimate, not a hard upper bound. SQLite has
    535 been demonstrated to work with 10 times that amount of traffic.” Here are some
    536 other SQLite success stories:
    537 
    538   • [102]Litestream is an open source tool that provides streaming replication
    539     for SQLite. Read author Ben Johnson’s article, [103]Why I Built Litestream.
    540   • Go developer David Crawshaw has an article about what he calls [104]“one
    541     process programming” (with Go and SQLite), that can be summed up with his
    542     phrase “don’t use N computers when 1 will do”. He also created a [105]Go
    543     SQLite library that supports more SQLite-specific features than the other
    544     drivers.
    545   • Peewee ORM author Charles Leifer wrote an article [106]“Five reasons you
    546     should use SQLite in 2016” that’s still very relevant in 2021. It ends with
    547     “I hope you’ll give SQLite a try. Don’t believe the FUD about it not being
    548     production-worthy, or not being suitable for use in web-applications.”
    549   • Sam Eaton of [107]Crave Cookie runs a $200,000 per month side business
    550     (wow!) using a single server and SQLite. Read his [108]Indie Hackers
    551     interview.
    552 
    553 Summing up
    554 
    555 Companies will do what companies do, and continue to make flashy-looking,
    556 bloated websites that “convert” well. Maybe you can have an influence at work,
    557 and come home to your better half and say “honey, I shrunk the web”. Or maybe
    558 you’ll just focus on the small web for your personal projects. (Disclaimer: I
    559 mostly do the latter – as part of my day job, I work on [109]Juju, which is not
    560 a small system by most measures.)
    561 
    562 Either way, I believe the “small web” is a compelling term and a compelling
    563 aesthetic. Not necessarily in the visual sense, but in the sense that you built
    564 it yourself, you understand all of it, and you run it on a single server or
    565 static file host.
    566 
    567 There are thousands of excellent examples of small websites, and hundreds of
    568 ways to create simple architectures – this essay touches on only a few of the
    569 ones I’m passionate about. I’d love to hear your own ideas and stories! Comment
    570 over at [110]Lobsters or [111]Hacker News or [112]programming Reddit.
    571 
    572 I’d love it if you [113]sponsored me on GitHub – it will motivate me to work on
    573 my open source projects and write more good content. Thanks!
    574 
    575 
    576 References:
    577 
    578 [1] https://benhoyt.com/
    579 [2] https://benhoyt.com/
    580 [3] https://benhoyt.com/cv/
    581 [4] https://benhoyt.com/projects/
    582 [5] https://benhoyt.com/writings/
    583 [6] https://benhoyt.com/writings/non-tech/
    584 [7] mailto:[email protected]
    585 [8] https://benhoyt.com/
    586 [9] mailto:[email protected]
    587 [10] https://benhoyt.com/writings/the-small-web-is-beautiful/#small-software
    588 [11] https://benhoyt.com/writings/the-small-web-is-beautiful/#small-websites
    589 [12] https://benhoyt.com/writings/the-small-web-is-beautiful/#emphasize-server-side-not-javascript
    590 [13] https://benhoyt.com/writings/the-small-web-is-beautiful/#static-sites-and-site-generators
    591 [14] https://benhoyt.com/writings/the-small-web-is-beautiful/#fewer-dependencies
    592 [15] https://benhoyt.com/writings/the-small-web-is-beautiful/#small-analytics
    593 [16] https://benhoyt.com/writings/the-small-web-is-beautiful/#small-architectures-not-microservices
    594 [17] https://basecamp.com/books
    595 [18] https://neustadt.fr/essays/the-small-web/
    596 [19] https://ar.al/2020/08/07/what-is-the-small-web/
    597 [20] https://en.wikipedia.org/wiki/Forth_(programming_language)
    598 [21] https://github.com/benhoyt/third
    599 [22] https://en.wikipedia.org/wiki/Demoscene
    600 [23] https://www.youtube.com/watch?v=jB0vBmiTr6o
    601 [24] https://www.youtube.com/watch?v=RCh3Q08HMfs
    602 [25] https://benhoyt.com/writings/the-small-web-is-beautiful/#fewer-dependencies
    603 [26] https://cr.yp.to/bib/1995/wirth.pdf
    604 [27] https://blog.brush.co.nz/2008/07/adobe-reader-9/
    605 [28] https://1mb.club/
    606 [29] https://news.ycombinator.com/item?id=25151773
    607 [30] https://512kb.club/
    608 [31] https://news.ycombinator.com/item?id=25450451
    609 [32] https://250kb.club/
    610 [33] https://news.ycombinator.com/item?id=25176663
    611 [34] https://10kbclub.com/
    612 [35] https://news.ycombinator.com/item?id=25556860
    613 [36] https://news.ycombinator.com/news
    614 [37] https://lobste.rs/
    615 [38] https://sourcehut.org/
    616 [39] https://forgeperf.org/
    617 [40] https://sqlite.org/
    618 [41] https://sqlite.org/testing.html
    619 [42] https://lwn.net/
    620 [43] https://lwn.net/Archives/GuestIndex/#Hoyt_Ben
    621 [44] https://danluu.com/
    622 [45] https://lucumr.pocoo.org/
    623 [46] https://nullprogram.com/
    624 [47] http://eradman.com/
    625 [48] https://hugotunius.se/
    626 [49] https://prog21.dadgum.com/
    627 [50] https://jvns.ca/
    628 [51] https://sjmulder.nl/en/textonly.html
    629 [52] https://giftyweddings.com/
    630 [53] https://news.ycombinator.com/item?id=26057078
    631 [54] https://news.ycombinator.com/item?id=11210860
    632 [55] https://indieweb.org/
    633 [56] https://small-tech.org/
    634 [57] https://news.ycombinator.com/item?id=24269071
    635 [58] https://indieweb.org/Homebrew_Website_Club
    636 [59] https://indieweb.org/IndieWebCamps
    637 [60] https://benhoyt.com/writings/seo-for-software-engineers/
    638 [61] https://stackoverflow.com/
    639 [62] https://blog.codinghorror.com/performance-is-a-feature/
    640 [63] https://news.ycombinator.com/
    641 [64] https://news.ycombinator.com/hn.js
    642 [65] https://news.ycombinator.com/item?id=23876281
    643 [66] https://alistapart.com/article/understandingprogressiveenhancement/
    644 [67] https://www.reddit.com/
    645 [68] https://github.com/turbolinks/turbolinks
    646 [69] https://turbo.hotwire.dev/
    647 [70] https://hey.com/
    648 [71] https://m.signalvnoise.com/html-over-the-wire/
    649 [72] https://alistapart.com/article/the-future-of-web-software-is-html-over-websockets/
    650 [73] https://benhoyt.com/writings/learning-elm/
    651 [74] https://pages.github.com/
    652 [75] https://jekyllrb.com/
    653 [76] https://gohugo.io/
    654 [77] https://staticsitegenerators.net/
    655 [78] https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/
    656 [79] https://github.com/juliangruber/isarray/blob/c9b0c5b4f44d366c9f51c7e85e70339bdeaa97b0/index.js#L3-L5
    657 [80] https://momentjs.com/
    658 [81] https://momentjs.com/docs/#/use-it/webpack/
    659 [82] https://date-fns.org/
    660 [83] https://golang.org/doc/modules/managing-dependencies
    661 [84] https://research.swtch.com/deps
    662 [85] https://go-proverbs.github.io/
    663 [86] http://youmightnotneedjquery.com/
    664 [87] https://casparwre.de/blog/stop-using-google-analytics/
    665 [88] https://lwn.net/Articles/822568/
    666 [89] https://www.goatcounter.com/
    667 [90] https://plausible.io/
    668 [91] https://lwn.net/Articles/824294/
    669 [92] https://www.theregister.com/2021/02/25/google_kubernetes_autopilot/
    670 [93] https://en.wikipedia.org/wiki/Conway%27s_law
    671 [94] https://m.signalvnoise.com/the-majestic-monolith/
    672 [95] https://duckduckgo.com/?t=canonical&q=why+not+microservices&ia=web
    673 [96] https://tailscale.com/blog/modules-monoliths-and-microservices/
    674 [97] https://stackexchange.com/performance
    675 [98] https://giftyweddings.com/
    676 [99] https://aws.amazon.com/ec2/instance-types/t2/
    677 [100] https://www.ansible.com/
    678 [101] https://sqlite.org/whentouse.html
    679 [102] https://litestream.io/
    680 [103] https://litestream.io/blog/why-i-built-litestream/
    681 [104] https://crawshaw.io/blog/one-process-programming-notes
    682 [105] https://github.com/crawshaw/sqlite
    683 [106] https://charlesleifer.com/blog/five-reasons-you-should-use-sqlite-in-2016/
    684 [107] https://cravecookie.com/
    685 [108] https://www.indiehackers.com/podcast/166-sam-eaton-of-crave-cookie
    686 [109] https://jaas.ai/
    687 [110] https://lobste.rs/s/d6qwff/small_web_is_beautiful
    688 [111] https://news.ycombinator.com/item?id=26305585
    689 [112] https://www.reddit.com/r/programming/comments/lvfdq9/the_small_web_is_beautiful/
    690 [113] https://github.com/sponsors/benhoyt/