def _retry_request(self, req_and_resp, _retry=0, **kwargs):
        """Uses self._request in a sane retry loop (for 5xx level errors).

        Do not use the _retry parameter, use the same params as _request

        Used when ESIClient is initialized with retry_requests=True
        if raise_on_error is True, this will only raise exception after
        all retry have been done

        """
        raise_on_error = kwargs.pop('raise_on_error', False)

        if _retry:
            # backoff delay loop in seconds: 0.01, 0.16, 0.81, 2.56, 6.25
            time.sleep(_retry ** 4 / 100)

        res = self._request(req_and_resp, **kwargs)

        if 500 <= res.status <= 599:
            _retry += 1
            if _retry < 5:
                LOGGER.warning(
                    "[failure #%d] %s %d: %r",
                    _retry,
                    req_and_resp[0].url,
                    res.status,
                    res.data,
                )
                return self._retry_request(
                    req_and_resp,
                    _retry=_retry,
                    raise_on_error=raise_on_error,
                    **kwargs
                )

        if res.status >= 400 and raise_on_error:
            raise APIException(
                req_and_resp[0].url,
                res.status,
                response=res.raw,
                request_param=req_and_resp[0].query,
                response_header=res.header
            )

        return res