В то же время, они основаны на системных потоках, размер которых не меньше 1Мб.
Вот в этом главное заблуждение. Горутины не основаны на системных потоках, системные потоки исполняют горутины. Горутина — это "задача", поток — "исполнитель". Исполнитель может исполнять задачу, пока она не будет выполнена или пока исполнителю есть что делать (а не ждать сеть или диск, например). После этого исполнитель ищет новую задачу. Для этого у него есть своя очередь задач. Если в ней что-то есть — исполняется это "что-то" (другая горутина). Если нет — исполнитель идёт в "глобальную очередь" и выгребает оттуда немного задач (больше одной). Если и в той очереди ничего нет, он идёт "воровать" (да, это буквально так называется — stealing) задачи из очередей других исполнителей (соседних потоков).
Так вот, поток далеко не равно горутина. У потока системный стек, у горутины — какой захочет рантайм го.