How can I count some rows before inserting?
Counting and subqueries are somewhat costly; let's try to avoid them.


If the latest question is less than 90 minutes ago, disallow.  This involves MAX() and an index on the timestamp column.
If 6 or more today (or today+yesterday), disallow.  This involves a summary table, see below.
If 50 or more ...  This involves the same summary table, plus a SUM() of only 30 rows, not 50, in worst case.  (OK that does not help much.)


Summary table something like...

CREATE TABLE Summary (
    author_id ...
    day DATE NOT NULL,
    ct TINYINT UNSIGNED,
    PRIMARY KEY(user_id, day)
) ENGINE=InnoDB;

INSERT INTO Summary (author_id, day, ct)
    VALUES (:id, CURRENT_DATE(), 1)
    ON DUPLICATE KEY UPDATE ct = ct+1;

-- How many "since midnight":
( SELECT ct FROM Summary WHERE author_id = :id
       AND day = CURRENT_DATE() ) &gt;= 6  -- disallow
-- How many "since midnight yesterday" (overkill; see below):
( SELECT SUM(ct) FROM Summary WHERE author_id = :id
       AND day &gt;= CURRENT_DATE() - INTERVAL 1 DAY ) &gt;= 6  -- disallow
( SELECT SUM(ct) FROM Summary WHERE author_id = :id
       AND day &gt;= CURRENT_DATE() - INTERVAL 50 DAY ) &gt;= 50  -- disallow


Sinece the second only checks for "6 in the last 2 days", it needs this to further check:

-- Exact count since this time yesterday:
( SELECT COUNT(*) FROM Qanda WHERE author_id = :id
       AND timestamp &gt; NOW() - INTERVAL 1 DAY ) &lt; 6


The query against the summary table should be faster, hence is probably worth doing as a quicker check.

I would define the limit as "6 since midnight" in order to simplify and speed up the checks.

Qanda needs INDEX(author_id, timestamp)