В зависимости от того, какой операционной системой вы пользуйтесь, ядро ОС выделяет фиксированный размер стэка для каждого из процессов. Обычно это не очень большая величина, и так например в моей Ubuntu это 8 МБ.
Как мне кажется, у вас просто исчерпывается адресное пространство (так как на стеке ещё находится много метаданных), и по этому интерпретатор запрещает Вам создавать дополнительные треды. Если вы уверены в том, что выделаете, и вам действительно надо 900 тредов, вы можете контролировать этот процесс вручную:
>>> import threading
>>> threading.stack_size()
0
>>> threading.stack_size(64*1024) # 64 KiB
А в случаи с Python и кроулерами, если кроулер сам по себе достаточно мал (что скорее всего правда, зависит от вашего кода), большую часть времени вы потратите на раундтрип до сервера и обратно за HTML-контентом. Т.е. 80-99% времени процессор будет простаивать, ожидания ответа от сетевого драйвера. В таких случаях я использую асинхронные вызовы и получаю прирост производительность в 4-8 раз по сравнению с синхронной программой и раза в 2 - по сравнению с многопоточной.