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/