Компактная и портабельная программа, четко выполняющая свое предназначение — редкая для современного мира красота и услада для глаз опытного разработчика.

Именно такие проекты, реализующие различные серверы и клиенты для веба вы найдете в этой статье.

Проект "Sandbird' в действии
Проект "Sandbird' в действии

Ода миниатюризации

Есть много причин, по которым миниатюрные девушк.. ээ реализации программ заслуживают внимания:

  • обучение — врядли получится разобраться как устроен вебсервер, перелопачивая исходники монстров вроде Apache или Nginx, спасет только миниатюрная реализация;

  • основа для собственных проектов — большой объем чужого исходного кода под капотом вашего проекта будет висеть гирей и отвлекать ресурсы на поддержку, в отличие от чего-то маленького и простого;

  • борьба с энтропией — популярные библиотеки постоянно растут и раздуваются, при этом объем используемого функционала не особо меняется. Таким образом, большая часть кода в современном проекте с кучей внешних библиотек не используется никогда.

Разумеется есть определенные риски использования таких «наколенных» библиотек, связанные с неполной реализацией, безопасностью, работой под нагрузкой и так далее.

Но говоря откровенно, всего этого ныне хватает с головой и в больших популярных реализациях.

Еще с опытом приходит понимание, что любая программа — не более чем инструмент а реальную опасность, как и сто лет назад, представляют живые люди, не машины.

Тестовое окружение

Не стал опять заморачиваться с BSD, чтобы в третий раз не описывать специальную прослойку epoll-shim, позволяющую быстро и более-менее безболезненно портировать серверный софт с линукса.

На этот раз в качестве тестового окружения выступает обычная Ubuntu Linux 25.10, хотя и с немного нестандартным ядром.

Компилятором выступит штатный GCC:

gcc version 15.2.0 (Ubuntu 15.2.0-4ubuntu4)

Поехали смотреть интересное!

Sandbird

https://github.com/rxi/sandbird

Начнем погружение с весьма практичного проекта:

A tiny (~800sloc) embeddable HTTP server written in C89, compatible with Linux, OSX and Windows.

800 строк на чистом С, причем наиболее портабельного стандарта С89, c поддержкой Windows, Linux и MacOS — отличный набор для реального применения, например в качестве встроенного вебсервера.

Например в каком-нибудь устройстве.

Один из примеров, демонстрирующих работу этой библиотеки — на заглавном скриншоте к статье, причем показана обработка формы.

Вот так выглядит сборка примера:

cd example
gcc hello.c ../src/*.c -I../src -std=c89 -pedantic -Wall -Wextra -o hello

Так выглядит код тестового приложения с использованием этой библиотеки:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sandbird.h"

static int event_handler(sb_Event *e) {
  if (e->type == SB_EV_REQUEST) {
    printf("%s - %s %s\n", e->address, e->method, e->path);
    sb_send_status(e->stream, 200, "OK");
    sb_send_header(e->stream, "Content-Type", "text/plain");
    sb_writef(e->stream, "Hello world");
  }
  return SB_RES_OK;
}

int main(void) {
  sb_Options opt;
  sb_Server *server;

  memset(&opt, 0, sizeof(opt));
  opt.port = "8000";
  opt.handler = event_handler;
  server = sb_new_server(&opt);

  if (!server) {
    fprintf(stderr, "failed to initialize server\n");
    exit(EXIT_FAILURE);
  }
  printf("Server running at http://localhost:%s\n", opt.port);

  for (;;) {
    sb_poll_server(server, 1000);
  }
  sb_close_server(server);
  return EXIT_SUCCESS;
}

Важный нюанс:

сервер не использует многопоточность, все клиентские обработчики работают в одном потоке.

зато с неблокирующими сокетами:

..
static void set_socket_non_blocking(sb_Socket sockfd) {
#ifdef _WIN32
  u_long mode = 1;
  ioctlsocket(sockfd, FIONBIO, &mode);
#else
  int flags = fcntl(sockfd, F_GETFL);
  fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
#endif
}
..

webs

https://github.com/nicholascok/webs

Следующий интересный и даже в чем-то уникальный проект, с лаконичным описанием:

a simple websocket server library.

Реализует с помощью ~700 строк на С89.. серверные вебсокеты!

Вебсокеты это чаты, это «live-streaming», это например отображение логов в реальном времени и тому подобные динамические штуки.

Так это выглядит в действии:

Статику отдает пример из предыдущего проекта.
Статику отдает пример из предыдущего проекта.

Так выглядит сборка тестового приложения:

gcc -c *.c examples/test.c -Wall -Wextra -Wpedantic -Wno-overlength-strings -std=c89
gcc -o webs *.o -lpthread

Как нетрудно догадаться по -lpthread, тут уже используется многопоточность на базе POSIX threads:

..
static void* __webs_main(void* _srv) {
	webs_server* srv = (webs_server*) _srv;
	webs_client* user_ptr;
	webs_client user;
	
	for (;;) {
		user.fd = __webs_accept_connection(srv->soc, &user);
		user.srv = srv;		
		if (user.fd >= 0) {
			user_ptr = __webs_add_client(srv, user);
			pthread_create(&user_ptr->thread, 0, __webs_client_main,
			 user_ptr);
		}
	}	
	return NULL;
}
..

К сожалению этот интересный проект по большей части прототип, иллюстрирующий как можно на коленке без внешних библиотек реализовать серверную сторону вебсокетов на чистом С.

В случае реального использования, столь вольное использование malloc для обработки входящих пакетов быстро превратится в проблему:

..
/* deal with normal frames (non-fragmented) */
		if (WEBSFR_GET_OPCODE(frm.info) != 0x0) {
			/* read data */
			if (data) free(data);
			data = malloc(frm.length + 1);
..		

Так выглядит сокращенная версия тестового сервера вебсокетов, c минимумом обработчиков:

#include "../webs.h"

int myFuncZ(webs_client* self) {
	printf("server %ld: (id %ld) connected!\n", 
	       self->srv->id, self->id);
	webs_send(self, "greetings, salutations!");
	return 0;
}
int myFunc2(webs_client* self) {
	printf("server %ld: (id %ld) disconnected!\n", 
	         self->srv->id, self->id);
	return 0;
}
int main(void) {
	webs_server* server1 = webs_start(7754);	
	if (!server1) {
		printf("failed to initialise a server.\n");
		return 1;
	}
	server1->events.on_open = myFuncZ;
	server1->events.on_close = myFunc2;
	
	webs_hold(server1);	
	webs_close(server1);	
	return 0;
}

Как видно из кода выше, все интересное происходит именно в обработчиках, где собственно и будет находиться ваша собственная логика, если вдруг решитесь использовать эту штуку.

Повторюсь, что весь этот проект, несмотря на всю свою интересность — сырой прототип и тащить в прод подобный код без переработки, "as-is" точно не стоит.

Собирается только для Linux и только с помощью gcc.

Прототип как он есть.

cpp-httplib

https://github.com/yhirose/cpp-httplib

Это уже более зрелая библиотека:

A C++ header-only HTTP/HTTPS server and client library

11к строк кода на C++11 и несколько зависимостей от внешних библиотек:

pthreads, brotli, OpenSSL, zlib

Реализуют весьма продвинутый HTTP/HTTPS сервер и клиент, причем фактически в одном файле. Есть поддержка сборки как на Linux так и Windows, причем для второй есть готовый проект для Visual Studio.

Разумеется это не мейнстрим и к качеству есть вопросы, зато все уместилось в очень небольшом коде, без особых ухищрений по миниатюризации и потому вполне читаемому.

Так выглядит сборка тестового сервера, использующего эту библиотеку:

g++ -o server -O2 -std=c++11 -I.. -Wall -Wextra -pthread \
  server.cc -DCPPHTTPLIB_OPENSSL_SUPPORT -lssl -lcrypto \
  -DCPPHTTPLIB_ZLIB_SUPPORT -lz -DCPPHTTPLIB_BROTLI_SUPPORT \
  -lbrotlicommon -lbrotlienc -lbrotlidec

Несложно догадаться по флагам вроде CPPHTTPLIB_ZLIB_SUPPORT, что большая часть зависимостей отключаема.

Еще думаю, заблудиться в 11к строчках кода и одном единственном файле будет проблематично даже у нейросети не самых опытных «плюсолюбов».

Так выглядит серверный «Hello, world!»:

#include <httplib.h>
using namespace httplib;

int main(void) {
  Server svr;

  svr.Get("/hi", [](const Request & /*req*/, Response &res) {
    res.set_content("Hello World!", "text/plain");
  });

  svr.listen("0.0.0.0", 8080);
}

В лучших традициях Django или Rails, тут есть маршрутизация запросов и привязка к URL — в данном случае обработчик связывается с урлом /hi.

Вот так выглядит обработка загрузки файлов с помощью формы и POST-запроса:

#include <fstream>
#include <httplib.h>
#include <iostream>
using namespace httplib;
using namespace std;

const char *html = R"(
<form id="formElem">
  <input type="file" name="image_file" accept="image/*">
  <input type="file" name="text_file" accept="text/*">
  <input type="submit">
</form>
<script>
  formElem.onsubmit = async (e) => {
    e.preventDefault();
    let res = await fetch('/post', {
      method: 'POST',
      body: new FormData(formElem)
    });
    console.log(await res.text());
  };
</script>
)";

int main(void) {
  Server svr;

  svr.Get("/", [](const Request & /*req*/, Response &res) {
    res.set_content(html, "text/html");
  });

  svr.Post("/post", [](const Request &req, Response &res) {
    const auto &image_file = req.form.get_file("image_file");
    const auto &text_file = req.form.get_file("text_file");

    cout << "image file length: " << image_file.content.length() << endl
         << "image file name: " << image_file.filename << endl
         << "text file length: " << text_file.content.length() << endl
         << "text file name: " << text_file.filename << endl;
    {
      ofstream ofs(image_file.filename, ios::binary);
      ofs << image_file.content;
    }
    {
      ofstream ofs(text_file.filename);
      ofs << text_file.content;
    }

    res.set_content("done", "text/plain");
  });

  svr.listen("localhost", 1234);
}

Так это выглядит в действии:

Разумеется подобный функционал — не откровение, особенно на 2026й год, но блин:

11к строк кода на всю красоту!

Теперь переходим к миниатюрным реализациям протокола FTP — для передачи файлов, если кто вдруг забыл.

tiny_ftpserver

https://github.com/adamwym/tiny_ftpserver

Вот такой «игрушечный» проект:

a tiny FTP server written in C++

Всего 1.5к строк на С++11 от безвестного китайского автора реализуют полнофункциональный FTP/FTPS‑сервер — с chroot, поддержкой локальных и анонимных юзеров и всем прочим.

FTPS это довольно редко встречающееся расширение протокола FTP, с поддержкой шифрования передачи данных. Не набравшее большой популярности ввиду появления SFTP и органичений самого FTP и потому мало известное широкой админской публике.

В работе:

Проект использует известную библиотеку libnet, о чем автор забыл сообщить и которую необходимо установить до сборки:

apt install libnet1-dev

Сама сборка происходит с помощью обычного cmake:

mkdir build && cd build
cmake ..

Реализация FTP-сервера тут максимально классическая — используется chroot а использование 21 и 20 портов зашито в код:

..
int socketfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_port = htons(21);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
..   

Все это означает, что запускать сервер придется от суперпользователя:

sudo ./tiny_ftpserver ../tiny_ftpserver.conf 

У этого проекта есть один неожиданный нюанс:

на самом деле это.. студенческая работа.

И подобных проектов на Github оказалось великое множество.

Так что далеко не везде в 2026м году забыли что такое высшее техническое образование, что не может не радовать.

fineFTP Server

https://github.com/eclipse-ecal/fineftp-server

Следующий интересный и весьма редкий проект:

FineFTP is a minimal FTP server library for Windows and Unix flavors.

~2k строк на С++14 реализуют FTP-сервер в виде.. библиотеки!

В этом и есть основная фишка этого проекта — возможность встроить FTP (причем сервер а не клиент) в ваше собственное приложение.

Так выглядит код примера, с внедрением FTP-сервера:

#include <fineftp/server.h>
#include <thread>
 
int main() {
  // Create an FTP Server on port 2121. We use 2121 instead of the default port
  // 21, as your application would need root privileges to open port 21.
  fineftp::FtpServer ftp_server(2121);
 
  // Add the well known anonymous user. Clients can log in using username
  // "anonymous" or "ftp" with any password. The user will be able to access
  // your C:\ drive and upload, download, create or delete files. On Linux just
  // replace "C:\\" with any valid path. FineFTP is designed to be cross-platform.
  ftp_server.addUserAnonymous("C:\\", fineftp::Permission::All);
  
  // Start the FTP Server with a thread-pool size of 4.
  ftp_server.start(4);
 
  // Prevent the application from exiting immediately
  for (;;) std::this_thread::sleep_for(std::chrono::milliseconds(100));
  return 0;
}

Зачем и для чего такое может быть нужно — другой вопрос, все же обычно работу с файлами в конечном приложении (например обновление прошивки) стараются реализовать в виде клиента и через HTTP/HTTPS.

Но с точки зрения использования все отлично работает:

Это хорошая, взрослая библиотека, с несколькими коммитерами, с историей разработки, которая активно поддерживается и развивается.

Старого цирка с chroot и 21м портом тут нет, поэтому все работает без привилегий суперпользователя — на скриншоте выше как раз видно использование нестандартного порта для работы.

Поддерживается сборка для Linux, MacOS и Windows c приоритетом для последней.

Отличный проект, но далеко не последний в сегодняшней подборке.

rcpd

https://github.com/tenox7/rcpd

Этот проект — привет из далекого и славного прошлого:

This is a modern re-implementation of rcp (remote copy protocol) daemon, originally part berkeley r-commands.

Да, это самый настоящий сервер RCP, всего 300 строк на Golang от знаменитого в узких кругах компьютерных реконструкторов автора Tenox.

RCP это такой устаревший протокол передачи файлов между компьютерами с UNIX, уже мало пригодный для использования в современных реалиях ввиду отсутствия какого-либо шифрования и авторизации.

Крайне актуальный, если имеете дело с устаревшим оборудованием или встраиваемыми системами, которые до сих пор используют именно rcp для загрузки прошивок по сети.

Возвращаясь к проекту:

rcpd от Tenox реализует серверную сторону — сервер RCP

К которому подключаются клиенты для загрузки или скачивания файлов.

Так выглядит процесс копирования файла, в качестве клиента тут rcp из пакета GNU Inetutils:

Как видите и клиент и сервер запускаются от суперпользователя — такие были времена, RCP использует 514 порт, который нельзя занять без привилегий.

Сборка:

go build -o rcpd .

Кстати в Makefile проекта есть поддержка кроссплатформенных сборок, с весьма богатым выбором:

Стоит добавить, что протокол RCP сам по себе очень простой и не менялся весь период своего существования, что позволяет подключаться к этому RCP-серверу даже с помощью клиентских программ из 80х и 90х.

За кадром

Детально разобрать удалось лишь малую часть интересных находок, поэтому ниже буквально одной строкой про интересные миниатюрные, точно заслуживающие внимания.

url.c

https://github.com/cozis/url.c/

Парсер строк URL на чистом С и без зависимостей:

This is a small library to parse and manipulate URLs in conformance to RFC 3986 and (most of) the WHATWG specification.

Что умеет:

  • No allocations

  • No dependencies

  • The ability to switch between RFC 3986 and WHATWG with a flag

  • Relative reference parsing and resolution

  • URL normalization

  • Doesn't rely on null-terminated strings

LightFTP

https://github.com/hfiref0x/LightFTP

Еще один интересный проект миниатюрного FTP-сервера:

Small x86-32/x64 FTP Server

Поддерживается сборка под Linux/Windows/Mac, сам проект не мертвый и судя по коммитам — развивается.

uftpserver

https://github.com/cpopp/MicroFTPServer

Весьма специфичная реализация FTP-сервера для встраиваемых систем:

Minimal FTP Server that can run on an ESP8266 with MicroPython

Так я впервые узнал о существовании «микропетона» — давно существующего проекта, с огромным количеством поддерживаемого железа и широким функционалом.

Ну и в качестве финального аккорда:

https://github.com/mtheall/ftpd

FTP Server for 3DS/Switch/Linux.

Реализация FTP-сервера для.. Nintendo Switch!

Это такая игровая консоль для гиков если кто вдруг не в курсе:

P.S.

Оригинал как обычно в нашем блоге, пользуясь случаем приглашаю на свой доклад 7 февраля для Analyst Marathon, посвященный проектированию совершенного API:

Комментарии (63)


  1. Jijiki
    05.02.2026 13:04

    только будет нужна многопоточка с менеджем того вызова малок, чтобы не было утечки, можно углубиться в воксели и там посмотреть как работает многопоточка(потом с полученными ) знаниями попробовать переосмыслить многопотоковый сервер с менеджером ресурсов без утечек )

    мне тематика вокселей вообще раскрыла глаза сейчас как мне кажется, там четко прям видна архитектура управления ресурсами


  1. vkrasikov
    05.02.2026 13:04

    Зашёл в статью из-за девушки на экране.

    Оказалось, она тут ни при чём.


    1. paunch73
      05.02.2026 13:04

      Три полоски, адидас кроссовки...


    1. Tuxman
      05.02.2026 13:04

      Я тоже так подумал - это про OpenCV как-то, чтобы на изображении что-то искать.


    1. Nostromo11
      05.02.2026 13:04

      Но рекламу-то получила хорошую, согласитесь!


    1. FireLynx
      05.02.2026 13:04

      Качественная настоящая КДПВ.


  1. Fima_Sobak
    05.02.2026 13:04

    В рай она не попадёт


    1. Remigrant
      05.02.2026 13:04

      Кто "она"? Девушка с КДПВ?


  1. endashru
    05.02.2026 13:04

    Интересная статья про минималистичный веб! Вышло здорово, в очередной раз показывает, что хорошее обращение с матчастью позволяет творить чудеса оптимизации :)


  1. achekalin
    05.02.2026 13:04

    Посыл про компактность поддерживаю, сейчас такого мало. Но вот что сразу на ум пришло:

    Маленький код проще прочитать и проаудитить. Но у «маленького веба» почти всегда отсутствует то, что делает сервер безопасным и предсказуемым в проде (да и просто при выставлении «голой задницей наружу»): годы работы в реальных условиях, совместимость по всем подробностям протокола, в т.ч. и с капризными и «маленькими» (как аллюзия на «маленький сервер») клиентами, покрытие тестами, эксплуатационные ограничения. В самой статье, кстати, автор упоминает риски «неполной реализации, безопасностью, работой под нагрузкой».

    Если всё это не закрывается — «красота и услада» остаются, но продовая эксплуатация превращается в рулетку: не потому что код сервера плохой (хотя автор пишет не всё сам, а использует чужие либы, скажем), а потому, что веб‑периметр нынче «жёсткий», и у больших серверов большая часть сложности — это плата за «выживание в реальности».

    Дарвин какой-то получается.


    1. alex0x08 Автор
      05.02.2026 13:04

      К сожалению "безопасность" мало зависит и от объема кода и от "годов работы в реальных условиях", все второстепенно.

      А первостепенны живые люди и их обучение.


      1. achekalin
        05.02.2026 13:04

        Годы опыта того же апача сделали из него (силами многих, конечно) весьма bulletproof софтину.


  1. nikhotmsk
    05.02.2026 13:04

    Можно упомянуть протокол Gemini для маленького интернета, Gopher, сообщество tilde, мастодон. Маленький веб всегда был, надо только поискать.


  1. gluck59
    05.02.2026 13:04

    Браво! Мне конечно до такого далеко, приятно видеть что кто-то понимает что комбайны-монстры не решают.

    Я тоже за минимализм. В профиле — пет-проект "мини-CRM для самых маленьких", и мне пока непонятно нужно ли кому такое. Или у всех "маленьких" уже оплачена подписка на корпоративщину типа 1С-управление-чего-то-там.


  1. woodiron
    05.02.2026 13:04

    Никогда не видел таких толстых (широких) домов, как на фото с девушкой. Или это дом буквой "Г"?


    1. alex0x08 Автор
      05.02.2026 13:04

      Это работа нейросети )


      1. Hrodvitnir
        05.02.2026 13:04

        Это Эльза в формате девушки из регионов в нулевых?)


        1. alex0x08 Автор
          05.02.2026 13:04

          С немного неудачным лицом да, закос под продавщицу )


        1. Soulskill
          05.02.2026 13:04

          Да, это маскот двачетреда


  1. Vedomir
    05.02.2026 13:04

    большой объем чужого исходного кода под капотом вашего проекта будет висеть гирей и отвлекать ресурсы на поддержку, в отличие от чего-то маленького и простого;

    борьба с энтропией — популярные библиотеки постоянно растут и раздуваются, при этом объем используемого функционала не особо меняется. Таким образом, большая часть кода в современном проекте с кучей внешних библиотек не используется никогда.

    Вот это как по мне очень распространенная обманка, которая губит массу проектов.

    Реальный мир сильно иначе работает и успех всех этих крупных систем с массой встроенного функциона обусловлен именно потребностями реального мира.

    Я помню это еще на пример MS Office одно время были очень популярны обсуждения в духе, что обычный пользователь использует дай бог 5% его функционала.

    И вроде бы еще Джоел Спольски писал статью, в которой очень справедливо отметил, что каждому отдельному пользователю может и нужно всего 5% функционала, вот только разным пользователям нужны разные 5% функционала.

    И сейчас это так же верно и для фреймворков в программировании например - сейчас мне нужно только 5% функционала, другим нужно другие 5%, а потом изменятся требования к моему проекту и мне тоже понадобятся другие 5%.

    В итоге система, в которой будут только эти 5%, никогда не обретет массового успеха и не получит экосистемных преимущество - накопленной базы документации, ответов и вопросв (в наша время обученных LLM), большого количества знающих ее соглашения людей и следовательно простоты нахождения сотрудников.

    Но для обучения и образования такие маленькие проекты, конечно, очень полезны.


    1. alex0x08 Автор
      05.02.2026 13:04

      Реальный мир сильно иначе работает и успех всех этих крупных систем с массой встроенного функциона обусловлен именно потребностями реального мира.

      Я тут гадаю с чего откровенно проходная статья привлекла столько внимания, а вы на полном серьезе рассказываете о причинах мировой славы и успеха у очень известных проектов..


      1. gluck59
        05.02.2026 13:04

        Просто в век копроративного "всего для всех" мы уже соскучились по минималистическому подходу...


      1. Vedomir
        05.02.2026 13:04

        Э-э... а вы самокритичны, ну так интернет работает и Хабр, кто-то случайно видит статью просто потому, что именно в это утро решил немного времени листанию Хабра посвятить, видит в ней цепляющее его утверждение о котором сам не раз раньше думал и реагирует в комментариях.


    1. unreal_undead2
      05.02.2026 13:04

      система, в которой будут только эти 5%, никогда не обретет массового успеха

      Сходу приходит на ум sqlite, который без огромного количества фич Oracle или Postgres используется более чем массово. Или какие-нибудь cat/grep/less... Так что минималистичные библиотеки/инструменты, хорошо решающие одну конкретную задачу, вполне востребованы.


      1. randomsimplenumber
        05.02.2026 13:04

        grep/less не светят в интернет, лишней точкой в regexp сложно устроить себе RCE


        1. unreal_undead2
          05.02.2026 13:04

          Как "светит в интернет" коррелирует с массовым успехом?


          1. randomsimplenumber
            05.02.2026 13:04

            Мелкие вещи для local host востребованы. А так есть куча мест где размер пофиг.


      1. Vedomir
        05.02.2026 13:04

        Sqlite я бы не назвал прямо минималистичным, учитывая то, что ее прямо позиционируют как альтернативу хранению данных просто в файлах.

        Think of SQLite not as a replacement for Oracle but as a replacement for fopen() https://sqlite.org/about.html

        Например в браузеры для JavaScript ее так и не смогли встроить - слишком сложно, слишком большая спецификация, короче фиг вам дорогие разработчики, а не sql, храните в json или ключ-значение и не выпендривайтесь. Но у нас есть обертки на js, которые имитируют sql базу поверх json-хранилища. Скорость? Не думайте об этом, это не для вас. Извиняюсь, отвлекся, в свое время знатно с этой истории пригорело как и со многих иных архитектурных решений в веб-разработке.

        cat/grep/less - да, но таких узких утилит не так много и они поставляются как часть очень большой и крупной операционной системы.

        Но само собой абсолютизм вреден и я не хотел сказать, что успеха добиваются только и исключительно крупные системы и иного не может быть в принципе. Но в большинстве случаев - да.


        1. unreal_undead2
          05.02.2026 13:04

          Согласен, смотря с чем сравнивать. В принципе есть и промежуточные варианты между файлами и sqlite типа gdbm. Но если хочется иметь SQL - вроде ничего легче sqlite нет и запользовать её в проекте на C/C++ весьма несложно.


          1. Vedomir
            05.02.2026 13:04

            Sqlite и Oracle/Postgre просто сильно разные задачи решают.


        1. p07a1330
          05.02.2026 13:04

          Скорость? Не думайте об этом, это не для вас.

          Если веб приложение по производительности упирается в скорость работы локальной БД - вы уже что-то делаете не так


          1. Vedomir
            05.02.2026 13:04

            Классическое наверное да, а если это PWA, которое должно работать без сети?

            Ну и плюс так навскидку, по общему пониманию, разница в скорости между нативной sql СУБД даже такой простой как sqlite хранящей данные в двоичном формате и имитирующей ее оберткой поверх json написанной на javascript должна быть просто огромной.

            В конце концов свои собственные данные на клиенте браузер хранит именно в sqlite, просто не показывает ее веб-приложениям.


          1. d3d11
            05.02.2026 13:04

            Что не так в ситуации, когда нагруженное веб-приложение упирается в пропускную способность БД?


            1. alex0x08 Автор
              05.02.2026 13:04

              У вас вообще термина "пропускная способность БД" быть не должно. Все что работает под высокой нагрузкой должно отдавать контент из памяти (кеш), но точно не из внешних ресурсов.


              1. d3d11
                05.02.2026 13:04

                Логично.


              1. d3d11
                05.02.2026 13:04

                А что насчет использования SQLite в памяти, с периодическим сбросом на диск?


                1. alex0x08 Автор
                  05.02.2026 13:04

                  Будет сильно хуже чем собственные структуры в памяти и собственный же сброс в хранилище.

                  Наш сайт на нашем же движке так и работает.


                  1. d3d11
                    05.02.2026 13:04

                    Это конечно, но свой memory state это все же больше key-value структура, а хотелось бы SQL, чтобы и условия в запросах и все такое...


                    1. alex0x08 Автор
                      05.02.2026 13:04

                      Если вы проектируете структуры хранения в памяти, никакой язык запроса просто не нужен.

                      Плюс транзакции и блокировки, из-за которых даже если вы файл с данными SQLite будете использовать из памяти - это будет все равно слишком медленно.


                      1. d3d11
                        05.02.2026 13:04

                        А как быть с полями неопределенного размера? Поле может быть 0 байт, может быть гигабайт. Выделять для них отдельные буферы?


                      1. alex0x08 Автор
                        05.02.2026 13:04

                        А физические ресурсы у вас тоже "неопределенного размера"? Память варьируется от 512Кб до 3Тб в пределах одной задачи?

                        И процессоров - от нуля до миллиона, ага.

                        Компьютеры тем и хороши (были до нейросетей), что в них не бывает неопределенности, всегда есть предсказуемый лимит.

                        Если включить голову и подумать, можно легко оценить все возможные размеры и схему хранения, где гигабайты самих данных будут храниться в дисковом массиве, а метаданные и связи - в памяти.


                      1. Siemargl
                        05.02.2026 13:04

                        Если вы проектируете структуры хранения в памяти, никакой язык запроса просто не нужен.

                        Ну почему же, конструкции типа linq и прочие map/reduce местами удобны


                      1. alex0x08 Автор
                        05.02.2026 13:04

                        Так вам удобство или скорость?

                        Мягкая подвеска на обычной машине и АКП - тоже очень удобны, но на спорткары их не ставят.


                      1. Siemargl
                        05.02.2026 13:04

                        Так вам удобство или скорость?

                        И то и другое. И ещё разумный расход памяти и по возможности, распараллеливание.

                        И все это достигается адекватным проектированием структур данных и применением готовых алгоритмов, например той же std::


                      1. Darkness_Paladin
                        05.02.2026 13:04

                        Если вы проектируете структуры хранения в памяти, никакой язык запроса просто не нужен.

                        Эдак любой абстрактор можно объявить ненужным, ибо без него всегда можно как-то обойтись. Вопрос лишь в том, насколько неудобно это будет.

                        Язык запросов с местом хранения данных никак не связан, он -- про удобство создания этих запросов.

                        Одно дело, если ваши данные -- один список с одним индексом (или даже без индекса), пусть даже и большой: вы один раз напишете несколько функций для работы с этим списком, и это закроет все возможные сценарии работы с ним, которые у вас могут возникнуть в работе над проектом, использующим эти данные.
                        Совсем другое дело, если данные имеют сколько-то сложную структуру -- без языка запросов вам придётся писать специальную функцию для каждой ерунды, и вы скоро обнаружите, что только этим и занимаетесь, вместо работы над кодом, реализующим логику обработки этих данных. А уж поддерживать потом этот код... ммм...

                        Короче, тут диалектика: универсально-правильного решения нет, оптимальное решение нужно выбирать под конкретную задачу. Где-то выгодно одно, где-то совсем другое, без учёта особенностей конкретной задачи сказать, какое решение лучше "вообще", нельзя.


                      1. alex0x08 Автор
                        05.02.2026 13:04

                        В длинном списке причин из "не знаю, не умею, не хочу, тут это не надо, не буду этого делать" обычно нет самого важного: "мне просто не дадут это сделать в текущем проекте".

                        Поэтому теоретизировать можно сколь угодно долго, на практике же есть ровно два варианта:

                        1) вас позвали именно ради оптимизаций и вы применяете все ваши таланты и известные методы оптимизации

                        2) все остальное

                        Второе это 99% проектов.


                  1. Diacut
                    05.02.2026 13:04

                    Красивый сайт. Но если убрать к чертям собачьим всю анимацию будет вообще замечательно. На третьем экране сдался и закрыл вкладку.


      1. SystemOutPrintln
        05.02.2026 13:04

        Сходу приходит на ум sqlite, который без огромного количества фич Oracle или Postgres используется более чем массово.

        Не уверен, что вообще корректно сравнивать эти СУБД...

        SQLite - это встраиваемая (embedded), в то время как Oracle и Postgres - это полнофункциональные клиент-серверные СУБД. Это абсолютно разные типы баз данных, и требования к ним, и сферы задач, которые они решают, совершенно разные.

        Это всё равно, что сравнивать между собой столовую ложку и миксер. Да, можно смешать смесь для выпечки с помощью ложки, а можно с помощью миксера, и это будет намного быстрее — но это же не значит, что ложки отстой, просто они предназначены, в общем-то, для иных целей, чем миксер.


        1. unreal_undead2
          05.02.2026 13:04

          Я же не спорю с тем, что минималистичные и полнофункциональные инструменты применяются для разных вещей (и соответственно востребованы и те и другие в зависимости от применения). Но в данном случае и то и другое позволяет с помощью SQL запросов наполнить базу и потом доставать из неё данные, так что сравнивать вполне можно )


          1. SystemOutPrintln
            05.02.2026 13:04

            Я хотел сказать, что SQLite и подобные ей встроенные СУБД хоть, как вы говорили выше, не имеют "огромного количества фич Oracle или Postgres", но зато у него (как и у других встраиваемых) есть две очень важные фичи, которых нет у вышеупомянутых СУБД. Это:

            простота использования (эту СУБД не требуется устанавливать как отдельный демон, не нужно настраивать, не нужен сервер - работа с ней идёт напрямую через библиотеку в приложении)

            переносимость (всё, что нужно, чтобы перенести эту базу на другую машину и даже другую ОС - это скопировать файл, и всё)

            То есть, эта СУБД массово используют не вопреки её простоте, а благодаря вышеупомянутым фичам, которыми ни Оракл, ни Постгря похвастаться не могут :)


        1. Siemargl
          05.02.2026 13:04

          Чаще сейчас используют миксер, когда хватило бы ложки

          И рассказывают, что ресурсов хватит всем, чего вы экономите


          1. SystemOutPrintln
            05.02.2026 13:04

            Именно

            А в особо клинических случаях подключают гигантскую либу ради единственной функции, которая при этом уже реализована в стандартных библиотеках языка и используется так же просто, как и в этой либе...

            И потом очень удивляются, когда показываешь им, как это сделать. "А что, так можно было?!"


    1. Darkness_Paladin
      05.02.2026 13:04

      Ну, губит или не губит, а портировать условный апач под esp32 ради того, чтоб коробочка-для-мигания-лампочкой могла управляться из браузера -- очевидно, крайне избыточно. Встройкам нужен предельно простой сервер без лишних наворотов


      1. Moog_Prodigy
        05.02.2026 13:04

        На тот же esp сервер пишется с готовой бибкой и 50 строк кода, из которых 30 - это сама вебморда на html. И даже при этом подходе там остается столько ресурсов, что хватает порулить чпу станком и даже чем посложнее. Не реалтайм, но где вы видели реалтайм + серверные применения?


  1. GooseWing
    05.02.2026 13:04

    А я просто `python -m http.server 8080` и дело в шляпе :)

    А если поинтересней хочется, то даже `pip install uploadserver` и `python -m uploadserver --basic-auth foobar:barfoo 8080`


    1. Qwest_Prozto
      05.02.2026 13:04

      питон в плане внешней легкости и прототипирования лучший язык. Конечно есть нюанс, что внешне простая либа внутри оказывается чем-то совершенно невменяемым.


      1. Moog_Prodigy
        05.02.2026 13:04

        У меня на orange pi zero 3 с 512 озушки уже год крутится файлообменник для локалки и даже не для локалки. Именно через питоновский запуск вебстранички. Гоняет через себя сотни гигабайт и хоть бы хны ему - 100 мбит\с вытягивает даже не напрягаясь, по спекам может до 1 гбита, но у меня локаль старого образца. Иногда я даю ему даже задачи типа "перекодировать разрешение фильма для просмотра на умных часах", и он в фоне это крутит, а чего ему будет, 4 ядра на 1,2 это позволяют.


    1. unreal_undead2
      05.02.2026 13:04

      А теперь затащите это на какой нибудь микроконтроллер ;)


  1. ant-s
    05.02.2026 13:04

    Статья фейк, у линуксоида не может быть такой девушки.


    1. alex0x08 Автор
      05.02.2026 13:04

      я BSD-шник ;)


      1. unreal_undead2
        05.02.2026 13:04

        Тогда почему без рожек и вил? )


    1. Vedomir
      05.02.2026 13:04

      Девушка фейк, веб-сервер настоящий, все по классике.


  1. lgorSL
    05.02.2026 13:04

    Четыре года назад ради интереса написал маленький сервер, который даёт скачивать файлики через браузер.

    https://github.com/Kright/files-web-server

    В сумме вроде 550 строчек, я про их количество вообще не думал. Что меня впечатлило - в отличие от самбы и прочих штук, за несколько лет использования на домашнем сервере проблем вообще не было и скорость приличная (упирается в скорость локальной сети).
    И ещё приятный момент, что написал сам и сам же использую.