Do MQTT brokers re-deliver un-acknowledged "QoS 1" messages from subscribers?
From [the spec]:
When a Client reconnects with CleanSession set to 0, both the Client and Server MUST re-send any unacknowledged PUBLISH Packets (where QoS > 0) and PUBREL Packets using their original Packet Identifiers [MQTT-4.4.0-1]. This is the only circumstance where a Client or Server is REQUIRED to redeliver messages.
So, yes, unacknowledged QOS1 messages will be redelivered but the only time the spec REQUIRES this to happen is when a client reconnects.
While you specificity state you are using MQTT v3.1.1 I believe it is worth noting that MQTT v5 expressly prohibits re-delivery other than following a reconnect:
When a Client reconnects with Clean Start set to 0 and a session is present, both the Client and Server MUST resend any unacknowledged PUBLISH packets (where QoS > 0) and PUBREL packets using their original Packet Identifiers. This is the only circumstance where a Client or Server is REQUIRED to resend messages. Clients and Servers MUST NOT resend messages at any other time
How much time must pass until MQTT broker re-deliver?
As per the above automatic retry is not required by the spec. Some brokers may retransmit after a period of time. emqx supports this; mosquitto used to have an option but this was removed in version 1.5 with the change log explaining:.
Outgoing messages with QoS>1 are no longer retried after a timeout period.
Messages will be retried when a client reconnects. This change in behaviour
can be justified by considering when the timeout may have occurred.
- If a connection is unreliable and has dropped, but without one end
noticing, the messages will be retried on reconnection. Sending
additional PUBLISH or PUBREL would not have changed anything.
- If a client is overloaded/unable to respond/has a slow connection then
sending additional PUBLISH or PUBREL would not help the client catch
up. Once the backlog has cleared the client will respond. If it is not
able to catch up, sending additional duplicates would not help either
Does the MQTT broker try endlessly to re-deliver an unacknowledged message?
The 3.11 spec does not provide any guidance (so, in theory, yes) but many brokers provide some control over this (maximum number of messages queued, max size of queue etc).
Are there other ways to trigger a re-delivery?
Yes - disconnect and reconnect.
Is it a good/valid idea to postpone sending the PUBACK until a received message was successfully persisted
There was a discussion re this on the paho-dev group a couple of months ago. Its something that is being considered in the Go v5 Client (currently that client automatically acknowledges messages).
One thing to note is that the MQTT spec does have requirements with regards to the order acknowledgments are sent. Many clients ignore this requirement (and just send the acknowledgments whenever the handler returns) but some (e.g. the HiveMQ Java client) queue up ACKs so they can be sent in the correct order.