As I said, everything is locally scripted in character scripts. The sleeping times for many NPCs are similar, but they're all locally scripted for each NPC. And since most NPCs don't have many actions to perform and sleeping times are very short - maybe to compensate the lack of actions and the lack of different text to say (both would have required more time and money) - NPCs repeat their actions and so their texts in high frequency, so it appears as 'looping' text whereas, in fact, they just repeat actions which the texts/dialogs are part of.
To give an example (the cheese vendor, of course):
This is the only action block he has:
REACTION Action_SellingWares, 0 //priority is actually 1100, set by the state manager system
USAGE PEACE
CHECK "c1"
IsEqual(%IsSelling, 1)
VARS
FLOAT:_Wait
ACTIONS
IF "c1"
IsRandom(0.33)
THEN
DialogStart(%DialogString, __Me)
GetRandomBetween(_Wait,3.0,6.0)
Sleep(_Wait)
ENDIF
IF "c1"
IsRandom(0.5)
THEN
CharacterMoveTo(%TalkingPoint_1, 0)
ELSE
CharacterMoveTo(%TalkingPoint_2, 0)
IF "!c1"
IsEqual(%Stock, null)
THEN
CharacterUseItem(%Stock)
ENDIF
ENDIF
SetPriority(%currentAction, 0)
INTERRUPT
SetPriority(%currentAction, 0)
As you see there's a chance of 33% that he starts to say his dialog (choosing different texts that are stored in the dialog), then sleeping time (doing nothing except playing the 'still' animation), then choosing one of two available points to move to (50% chance) and at the end 'currentAction' is set priority 0. After that the priority is set to 1100 again, since it's the only reaction in the script for him to choose from.
And that's how all NPCs work. No global delay set by Osiris or the engine itself.
Therefore I have modified almost every relevant character script for my QuietDayOnTheMarket mod to address this issue. Although it's really a relief to play with it, I always feel the need of a much more living world, a living world that even works without much background voices. That's what I'm working on for about half a year now.